0

Я переопределил AdminModel's ModelForm, чтобы сделать User полей съедобных и savable от Person's admin изменить форму.Как проверить метод ModelForm save() сохраняет изменения в модели?

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) 

Однако я борюсь с написанием теста, который проверяет сохранить() метод:

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") 

ответ

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',) 
    ... 
+0

Это возвращает 'ValueError: Человек не может быть изменен, так как данные не validate.' –

+1

' self.assertEquals (user.first_name, "has_changed") 'будет по определению терпеть неудачу, поскольку данные в' user' не перезагружаются из базы данных, поэтому его нельзя изменить. – knbk

+0

Как сделать personform действительным или что сделало его недействительным? –

1

Передайте новый данные как словарь для y наша форма (как первый позиционный аргумент или как data), и утверждают, что personform.cleaned_data['name'] равно User.objects.get(pk=user.pk).username. Затем сделайте то же самое для surname и email.

Обратите внимание, что first_name и last_name имеют max_length 30, в то время как ваши поля формы имеют max_length 100.