如何使用Form?元数据字段中未指定的字段进行POST?

时间:2017-07-25 02:12:53

标签: python django django-models django-forms

我只想将referenceData添加到class Meta字段并使用它,但<select>的选项数量太高,所以我没有添加{reference。 1}}字段到ModelForm然后读取此值引用的数据记录。但是,POST完成后,只会丢失referenceData字段并创建数据。

views.py

    class CorrectView(IndexView):
        ...
        form_class = DataCorrectForm
        ...
        def post(self, request, *args, **kwargs):
            form = self.form_class(request.POST or None)
            if form.is_valid():            
                the_form = form.save(commit=False) 
                the_form.clean() # HERE !
                the_form.save()  # HERE !
                return self.form_valid(form)
            else:
                return self.form_invalid(form)

forms.py

    class DataCorrectForm(forms.ModelForm):
        reference = forms.IntegerField()
        def clean(self):
            cleaned_data = super(DataCorrectForm, self).clean()
            cleaned_data['referenceData'] = DataNeedsCorrection.objects.get(data_id=cleaned_data['reference']) 
            # I extract a record that matches data_id and assign it to the form data
            return cleaned_data


        def save(self, commit=True):
            return super(DataCorrectForm, self).save(commit=commit)


        class Meta:
            model = DataCorrected
            fields = [
                'reference',
                 # 'referenceData', # If I comment this out it works! but not that I wanted 
                'correctedText',
            ]

如果我注释掉'referenceData',至少POST工作和数据记录已正确创建,但这是一种无法采用的方法。

models.py

    class DataCorrected(models.Model):
        data_id = models.AutoField(primary_key=True)
        referenceData = models.ForeignKey('DataNeedsCorrection', on_delete=models.CASCADE, null=True)
        correctedText = models.CharField(max_length=300)
        ...

    class DataNeedsCorrection(models.Model):
        data_id = models.AutoField(primary_key=True)
        category = models.ForeignKey('WatCategory', on_delete=models.CASCADE)
        originalText = models.CharField(max_length=300)
        translatedText = models.CharField(max_length=300)
        ...

当前DataCorrected模型为null = True,但请注意,这是我测试它所做的。

如果您能指出任何其他改进,我将非常感激。谢谢你的阅读。

我将self.fields['referenceData']更新为None字段,因此我可以隐藏许多字段。下面,我发布了该页面的快照。

enter image description here

如您所见,如果用户单击数据列表中的行,javascript将更新referenceData,reference和correctedText字段的值。并且用户最终确定modifiedText并提交它。

以下是问题所在。

  1. 如果我在django表单字段中使用referenceData字段,它会在前端显示太多字段(大约100,000行无法选择)。

  2. 所以我尝试self.fields['referenceData'] = DataNeedsCorrection.objects.none(). 这可以有效地隐藏字段,但它不响应document.getElementById('id_referenceData').value = some_id,因为它没有选项值。所以我无法提交表格。

1 个答案:

答案 0 :(得分:2)

杰森。另一种方法是在表单的Meta类中包含您想要的字段,并使用__init__方法的形式更改查询集。

class DataCorrectForm(forms.ModelForm):
    reference = forms.IntegerField()
    def clean(self):
        cleaned_data = super(DataCorrectForm, self).clean()
        cleaned_data['referenceData'] = DataNeedsCorrection.objects.get(data_id=cleaned_data['reference']) 
        # I extract a record that matches data_id and assign it to the form data
        return cleaned_data


    def save(self, commit=True):
        return super(DataCorrectForm, self).save(commit=commit)


    class Meta:
        model = DataCorrected
        fields = [
            'reference',
            'referenceData',
            'correctedText',
        ]

    def __init__(self, *args, **kwargs):
        super(DataCorrectForm, self).__init__(*args, **kwargs)
        self.field['referenceData'].queryset = DataNeedsCorrection.objects.none()

如果这与您正在寻找的内容不符,请告诉我(因此我可以将其删除或提供其他解决方案)。

我建议的其他更改:

  • 您在表单中覆盖了save方法,但没有做任何新的事情。我删除了。

  • 删除the_form.clean()。这发生在form.is_valid()

  • 我不确定IndexView是什么,但如果它继承自FormView,则不需要整个post方法。

  • Django已经提供了主键,因此您不需要添加AutoFields