Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Django ModelForm中保存到数据库之前,如何转换表单字段数据?_Django_Python 3.x - Fatal编程技术网

在Django ModelForm中保存到数据库之前,如何转换表单字段数据?

在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”的数据转换可以按如下方式实现(示例): 我的表单需要向用户显示人

我正在Django python框架中创建一个“编辑”页面(模板“edit_page.html”),用户应该能够编辑存储在数据库中的现有数据。现在我可以轻松地检索用户表单(Django模板)中现有的原始数据,我的问题是在保存表单之前需要转换用户填充的数据

我的模型中有一个“ipv4”字段映射数据库表列,其中ipv4地址存储为unsigned int。例如,ip地址“10.0.0.0”在数据库中存储为167772160。 “ipv4”的数据转换可以按如下方式实现(示例):

我的表单需要向用户显示人性化的“ipv4”,但必须能够以“原始”格式(int)更新数据库列

“ipv4”必须从原始格式转换为用户友好的格式才能显示,反之亦然才能更新数据库

我应该在哪里执行此操作,如何执行?到目前为止,我有以下实现,其中IP以原始格式显示

型号.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
    })
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}}