【问题标题】:How to test ModelForm save() method saves changes in model?如何测试 ModelForm save() 方法保存模型中的更改?
【发布时间】:2015-03-13 03:47:51
【问题描述】:

我已覆盖 AdminModelModelForm 以使 User 字段可从 Person 的管理员更改表单中食用和保存。

class Person(models.Model):
    user = models.OneToOneField(User)
    #and also some char, text fields

    @property
    def name(self):
        return self.user.first_name
    @name.setter
    def name(self, value):
        self.user.first_name = value

    #and by analogy surname and email properties


class PersonForm(ModelForm):
    class Meta:
        model = Person

    name = forms.CharField(max_length=100, required=False)
    surname = forms.CharField(max_length=100, required=False)
    email = forms.EmailField(required=False)

    def save(self, commit=True):
        instance = super(PersonForm, self).save(commit)  
        user = instance.user
        user.first_name = self.cleaned_data['name']
        user.last_name = self.cleaned_data['surname']
        user.email = self.cleaned_data['email']
        user.save()
        return instance

class PersonAdmin(admin.ModelAdmin):
    fields = ['name', 'surname', 'email', 'and_others']

    form = PersonForm

admin.site.register(Person, PersonAdmin)

但是我正在努力编写一个检查 save() 方法的测试:

def test_form_saves_values_to_instance_user_on_save(self):
    """
    test that, form saves name, surname, email values to corresponding User
    when commiting form
    """
    user = User.objects.get(username='admin')
    person = Person.objects.get(user=user)
    personform = PersonForm(instance=person, data={'name': 'has_changed'})

    # if uncommented raisesValueError: The Person could not be changed
    # because the data didn't validate.
    # personform.save()

    self.assertEquals("has_changed", User.objects.get(pk=user.pk).first_name)

更新测试

更新解决方案。原来我没有填写请求的不可见字段“用户”。排除使表格有效并通过测试。

admin.py

class PersonForm(ModelForm):
    class Meta:
        model = Person
        exclude = ('user',)
# ...

tests.py

def test_form_saves_values_to_instance_user_on_save(self):
    """
    test that, form saves name, surname, email values to corresponding User
    when commiting form
    """

    person = Person.objects.get(user__username='admin')
    personform = PersonForm(instance=person, data={'name': 'has_changed'})

    if personform.is_valid():
        person = personform.save()
        self.assertEquals(User.objects.get(pk=person.user.pk).first_name, "has_changed")
    else:
        self.fail("personform not valid")

【问题讨论】:

    标签: python django django-forms django-testing django-modeladmin


    【解决方案1】:
    def test_form_saves_values_to_instance_user_on_save(self):
        """
        test form saves name, surname, email values to corresponding User object
        when commiting form
        """
        person = Person.objects.get(user__username='admin')
        personform = PersonForm(instance=person, data={'name': 'has_changed'})
    
        if personform.is_valid():
            person = personform.save()
            self.assertEquals(person.user.first_name, "has_changed")
        else:
            self.fail("personform not valid")
    

    我认为您还需要从表单中排除 user 字段

    class PersonForm(ModelForm):
        class Meta:
            model = Person
            exclude = ('user',)
        ...
    

    【讨论】:

    • 返回ValueError: The Person could not be changed because the data didn't validate.
    • self.assertEquals(user.first_name, "has_changed") 根据定义会失败,因为user 中的数据不会从数据库中重新加载,因此无法更改。
    • 如何使personform有效或者是什么使它无效?
    • @knbk 我认为现在已修复
    • 我只是没有在字段中包含“用户”
    【解决方案2】:

    将新数据作为字典传递给表单(作为第一个位置参数或data),并断言personform.cleaned_data['name'] 等于User.objects.get(pk=user.pk).username。然后对surnameemail 执行相同的操作。

    请注意,first_namelast_namemax_length 为 30,而您的表单字段的 max_length 为 100。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-12
      • 1970-01-01
      • 2011-06-12
      • 2016-11-08
      • 1970-01-01
      • 2013-11-19
      • 2022-08-23
      相关资源
      最近更新 更多