简体   繁体   English

发布到 Django 表单时,是否发布了所有字段?

[英]When posting to a Django form, are all fields posted?

I'm trying to write a test for a form to simulate the situation in which I'd like to update just one field.我正在尝试为表单编写测试以模拟我只想更新一个字段的情况。 Here is the test:这是测试:

from django.test import TestCase
from django.forms.models import model_to_dict

class FamilyDemographicsUpdateTest(TestCase):
    def test_update_phone_types_with_fields_from_family_factory(self):
        # Create a family for which the employee uses an iPhone
        family = FamilyFactory(employee_phone_type=Family.IPHONE)
        url = reverse('dashboard:family', kwargs={'pk': family.id, 'tab': 'family-demographics'})

        data = model_to_dict(instance=family, fields=FamilyDemographicsForm.base_fields)

        form = FamilyDemographicsForm(data=data)

after which I drop into the debugger with import ipdb; ipdb.set_trace()之后我使用import ipdb; ipdb.set_trace()进入调试器import ipdb; ipdb.set_trace() import ipdb; ipdb.set_trace() . import ipdb; ipdb.set_trace() It is here that I notice that the form has errors :在这里,我注意到formerrors

ipdb> form.errors
{'employee_email': ['This email is already taken.']}

This can be traced back to the Family model on which the form is based.这可以追溯到表单所基于的Family模型。 The form is a ModelForm :表单是一个ModelForm

class FamilyDemographicsForm(forms.ModelForm):
    class Meta:
        model = Family

The view is based on Django's generic UpdateView :该视图基于 Django 的通用UpdateView

class FamilyUpdate(SuccessMessageMixin, DashboardAccessMixin, UpdateView):
    template_name = 'families/edit.html'
    model = Family
    success_message = "Family was updated successfully."

    def get_form_class(self, **kwargs):
        tab = self.kwargs['tab']
        if tab == 'family-demographics':
            return FamilyDemographicsForm

and the corresponding Family object has a clean() method which is triggering this error (in class Family(models.Model) ):并且相应的Family对象有一个clean()方法,它会触发此错误(在class Family(models.Model) ):

def clean(self):
    if self.employee_email:
        db_user = User.objects.filter(username=self.employee_email).first()
        if db_user and db_user.family and db_user.family != self:
            raise ValidationError({'employee_email': 'This email is already taken.'})
    if self.partner_email:
        db_user = User.objects.filter(username=self.partner_email).first()
        if db_user and db_user.family and db_user.family != self:
            raise ValidationError({'partner_email': 'This email is already taken.'})

However, if I actually use the form in the browser and submit, it seems to work just fine.但是,如果我真的在浏览器中使用表单并提交,它似乎工作得很好。 In short, when you submit a form in the browser, is that not equivalent to post ing data which is - for the fields that you haven't changed - are the same as they initially were?简而言之,当您在浏览器中提交表单时,这不等同于post数据 - 对于您尚未更改的字段 - 与最初相同吗? Why is this error getting triggered in this test and not in the browser?为什么会在此测试中而不是在浏览器中触发此错误?

This doesn't have anything to do with posting data at all.这与发布数据根本没有任何关系。 The issue is that your view is an update, which passes the existing instance to the form so that Django knows how to update it.问题是您的视图是一个更新,它将现有实例传递给表单,以便 Django 知道如何更新它。 Your test doesn't do that.你的测试不这样做。

(Your test isn't really testing your code; you should really be calling the view, either with the request factory or the test client, v and passing your data in there.) (您的测试并不是真正测试您的代码;您真的应该使用请求工厂或测试客户端 v 调用视图并将数据传递到那里。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM