在Django ModelForm中保存到数据库之前,如何转换表单字段数据?
我正在Django python框架中创建一个“编辑”页面(模板“edit_page.html”),用户应该能够编辑存储在数据库中的现有数据。现在我可以轻松地检索用户表单(Django模板)中现有的原始数据,我的问题是在保存表单之前需要转换用户填充的数据 我的模型中有一个“ipv4”字段映射数据库表列,其中ipv4地址存储为unsigned int。例如,ip地址“10.0.0.0”在数据库中存储为167772160。 “ipv4”的数据转换可以按如下方式实现(示例): 我的表单需要向用户显示人性化的“ipv4”,但必须能够以“原始”格式(int)更新数据库列 “ipv4”必须从原始格式转换为用户友好的格式才能显示,反之亦然才能更新数据库 我应该在哪里执行此操作,如何执行?到目前为止,我有以下实现,其中IP以原始格式显示 型号.py在Django ModelForm中保存到数据库之前,如何转换表单字段数据?,django,python-3.x,Django,Python 3.x,我正在Django python框架中创建一个“编辑”页面(模板“edit_page.html”),用户应该能够编辑存储在数据库中的现有数据。现在我可以轻松地检索用户表单(Django模板)中现有的原始数据,我的问题是在保存表单之前需要转换用户填充的数据 我的模型中有一个“ipv4”字段映射数据库表列,其中ipv4地址存储为unsigned int。例如,ip地址“10.0.0.0”在数据库中存储为167772160。 “ipv4”的数据转换可以按如下方式实现(示例): 我的表单需要向用户显示人
from django.db import models
class Items(models.Model):
ipv4 = models.PositiveIntegerField()
class Meta:
managed = False
db_table = 'Items'
from django import forms
from .models import Items
MyEditForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['ipv4'] = forms.CharField(label='IPv4',widget=forms.TextInput(attrs={ 'class': 'form-control' }))
def clean_ip(self):
import ipaddress
ip = int(ipaddress.ip_address(self.cleaned_data['ipv4']))
return ipv4
class Meta(object):
model = Items
fields = ('ipv4')
def item_edit(request,item_id):
item_id = int(item_id)
item = Items.objects.get(id = item_id)
redirect_url = 'https://domain.tld/items/' + str(item_id)
if request.method == 'POST':
my_edit_form = MyEditForm(request.POST,instance=item)
if my_edit_form.is_valid():
my_edit_form.save()
return redirect(redirect_url)
else:
my_edit_form = MyEditForm(instance=item)
return render(request,'device_edit_form.html',{
'item': item,
'my_edit_form': my_edit_form
})
forms.py
from django.db import models
class Items(models.Model):
ipv4 = models.PositiveIntegerField()
class Meta:
managed = False
db_table = 'Items'
from django import forms
from .models import Items
MyEditForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['ipv4'] = forms.CharField(label='IPv4',widget=forms.TextInput(attrs={ 'class': 'form-control' }))
def clean_ip(self):
import ipaddress
ip = int(ipaddress.ip_address(self.cleaned_data['ipv4']))
return ipv4
class Meta(object):
model = Items
fields = ('ipv4')
def item_edit(request,item_id):
item_id = int(item_id)
item = Items.objects.get(id = item_id)
redirect_url = 'https://domain.tld/items/' + str(item_id)
if request.method == 'POST':
my_edit_form = MyEditForm(request.POST,instance=item)
if my_edit_form.is_valid():
my_edit_form.save()
return redirect(redirect_url)
else:
my_edit_form = MyEditForm(instance=item)
return render(request,'device_edit_form.html',{
'item': item,
'my_edit_form': my_edit_form
})
视图.py
from django.db import models
class Items(models.Model):
ipv4 = models.PositiveIntegerField()
class Meta:
managed = False
db_table = 'Items'
from django import forms
from .models import Items
MyEditForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['ipv4'] = forms.CharField(label='IPv4',widget=forms.TextInput(attrs={ 'class': 'form-control' }))
def clean_ip(self):
import ipaddress
ip = int(ipaddress.ip_address(self.cleaned_data['ipv4']))
return ipv4
class Meta(object):
model = Items
fields = ('ipv4')
def item_edit(request,item_id):
item_id = int(item_id)
item = Items.objects.get(id = item_id)
redirect_url = 'https://domain.tld/items/' + str(item_id)
if request.method == 'POST':
my_edit_form = MyEditForm(request.POST,instance=item)
if my_edit_form.is_valid():
my_edit_form.save()
return redirect(redirect_url)
else:
my_edit_form = MyEditForm(instance=item)
return render(request,'device_edit_form.html',{
'item': item,
'my_edit_form': my_edit_form
})
editpage.html
{% block page_content %}
<form id="my-edit-form" method="post" action="" role="form">
{% csrf_token %}
<div class="form-group">
{{ my_edit_form.ipv4.label_tag }}
{{ my_edit_form.ipv4 }}
</div>
</form>
{% endblock %}
{%block page\u content%}
{%csrf_令牌%}
{{my_edit_form.ipv4.label_tag}
{{my_edit_form.ipv4}
{%endblock%}
您可以创建自定义字段,例如:
import ipaddress
class MyIPField(forms.CharField):
def prepare_value(self, value):
if value:
return str(ipaddress.ip_address(value))
return value
def to_python(self, value):
try:
ip = int(ipaddress.ip_address(value))
except ValueError:
raise ValidationError('Not valid IP address')
return ip
并以\uuuu init\uuuu
的形式引用它:
self.fields['ipv4'] = MyIPField(label='IPv4', widget=forms.TextInput(attrs={'class': 'form-control'}))
在这种情况下,您不需要clean\u ip
方法
另一种解决方案是使用两个模型字段(用于原始ip和友好ip),并在表单验证顺利后手动保存原始值。谢谢,当字段具有有效ip时,如果“ipv4”有效,则此方法会正常工作,但当输入的数据不是预期类型时会引发错误,从而阻止呈现模板页面。在这种情况下,为什么表单错误字段机制不处理错误(例如ipv4.errors)?我如何在UI中显示错误,例如:{{my_edit{u form.ipv4.name}:{{ipv4.errors}}?