【问题标题】:Django form custom fieldDjango 表单自定义字段
【发布时间】:2017-12-17 00:17:17
【问题描述】:

如果我们有一个modelForm,其中一些字段不直接对应于模型,我们如何让表单以自定义方式处理它们,同时默认保存其余字段?

例如,我们有一个支持多语言描述的项目模型。这些模型是:

class Item(models.Model):
    name = models.ForeignKey(Localization)
    on_sale = models.BooleanField(default=False)

class Localization(models.Model):
    de = models.TextField(blank=True, null=True, verbose_name='de')
    eng = models.TextField(blank=True, null=True, verbose_name='eng')

添加/编辑项目的表单如下所示:

class ItemForm(forms.ModelForm):
    id = forms.CharField(widget=forms.HiddenInput(), max_length=128, label='')
    name_eng = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:200px;'}), label='eng')
    name_de = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:200px;'}), label='de')
    on_sale = forms.CharField(widget=forms.CheckboxInput(), label='on_sale', )

    class Meta:
        model = Item
        fields = ('id', 'on_sale',)

现在保存这个表单应该做的是为一个新的项目 - 创建具有两个名称字段的本地化对象,然后创建一个具有 on_sale 字段的项目对象,链接到本地​​化对象。对于现有项目 - 编辑相应的本地化对象,然后编辑项目本身的 on_sale 字段。

我使用一个单独的函数完成了这项任务,该函数分别处理来自请求的自定义字段,但是通过表单的 save() 方法完成这一切看起来更好。还是我错了?

PS 很抱歉提出一个明显陈词滥调的问题,但我只是没能用其他例子做我想做的事。

更新:

在此处的提示的帮助下,我实际上让它按照我想要的方式工作。代码是这样的,请告诉我是否可以优化。

class NameForm(forms.ModelForm):
    # id = forms.CharField(widget=forms.HiddenInput(), max_length=128, label='')
    id = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:200px;'}), label='id', required=False)
    name_eng = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:200px;'}), label='eng')
    name_de = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:200px;'}), label='de')
    gender = forms.CharField(widget=forms.CheckboxInput(), label='gender', required=False)

    class Meta:
        model = Name
        fields = ('id', 'gender',)

    def save(self):
        instance = super(NameForm, self).save(commit=False)
        obj_id = self.cleaned_data['id']
        if obj_id:
            instance_bd = Name.objects.get(pk=obj_id)
            loc = instance_bd.name
            loc.de = self.cleaned_data['name_de']
            loc.eng = self.cleaned_data['name_eng']
            loc.save()
            instance.id = obj_id
        else:
            loc = Localization(de=self.cleaned_data['name_de'], eng=self.cleaned_data['name_eng'])
            loc.save()
        instance.name = loc
        instance.save()
        return instance

视图很简单

@login_required
def admin_lists(request):
    if request.method == 'POST':
        form = NameForm(request.POST)
        if form.is_valid():
            form.save()
    forms = {'name': NameForm()}
    return render(request, 'admin/lists.html', {'forms': forms})

【问题讨论】:

  • 您在views.py 的表单验证中寻找的是commit=false。看看这里stackoverflow.com/questions/12848605/…。发表你的意见。py 也许我可以告诉你我的意思。
  • @hansTheFranz 谢谢。我实际上让它按照我想要的方式工作,上面的代码。如果有任何可能的改进,请告诉我。

标签: python django forms


【解决方案1】:

这种情况最好不要使用表单的保存方法,试试这个

if request.method == 'POST':
    form = ItemForm(request.POST)
    # check whether it's valid:
    if form.is_valid():
        post = request.POST
        set_name_eng= post['name_eng']
        set_name_de= post['name_de']
        set_on_sale = post['on_sale']

        #now here we create the anothers objects
        a = Localization(de=set_name_de, eng=set_name_eng)
        a.save()

        b = Item(name=a, on_sale=sale)
        b.save()

我没看懂最后一部分,但我认为你需要更好地组织你的模型和表单,让我知道,我会尽力帮助你

【讨论】:

  • 感谢您的评论。为什么这种方法比使用表单的 save() 方法更好?
  • 在这种情况下,您需要修改来自其他模型的数据而不仅仅是模型表单,但例如在大型模型表单中非常有用 save(),您也可以将这两种方法与 .save(commit =假)
猜你喜欢
  • 2014-01-12
  • 2015-09-14
  • 2021-06-07
  • 2012-12-11
  • 1970-01-01
  • 2011-12-02
  • 2022-11-11
  • 1970-01-01
  • 2010-12-26
相关资源
最近更新 更多