V
V
Vampre2020-01-06 07:27:37
Django
Vampre, 2020-01-06 07:27:37

Why doesn't is_valid work for ModelForm when passing instance?

I override the user model:

# models.py

class CustomConfirmedUser(AbstractBaseUser, PermissionsMixin):
    """Модель юзера с опцией подтверждени по имеил, наследуется от AbstractBaseUser"""

    email = models.EmailField("Email пользователя", max_length=128, unique=True)
    username = models.CharField("Логин пользователя", max_length=128, unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    confirm = models.BooleanField("Пользователь подтвержден", default=False)

    objects = CustomUserManager()
    confirmed = CustomConfirmedManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email',]

    def get_full_name(self):
        return self.username

    def get_short_name(self):
        return self.username

# forms.py

class CustomConfirmedUserChangeForm(forms.ModelForm):
    """Форма для редактирования CustomConfirmedUser"""
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = CustomConfirmedUser
        fields = ('username', 'email', 'confirm', 'password', 'is_staff', 'is_superuser')

    def clean_password(self):
        return self.initial['password']

# tests.py

class TestCustomUserChangeForm(TestCase):

    def setUp(self):
        self.username = 'test'
        self.email = '[email protected]'
        self.password = 'password123'
        self.user = CustomConfirmedUser.objects.create_user(
            self.username,
            self.email,
            self.password
        )

    def test_clean_password(self):
        form = CustomConfirmedUserChangeForm(
            {'username': 'newtest',},
            instance=self.user
        )
        form.is_valid()
        print(form.initial)
        print(form.errors)
        self.assertTrue(form.is_valid())

As a result I get:
{'password': 'pbkdf2_sha256$150000$nGiR5RBeDrAU$7s+IaSLRR3W/io1W7jQahjLRBGitxOwmvDXtEeD83/A=', 'is_superuser': False, 'email': '[email protected]', 'username': 'test', 'is_staff': False, 'confirm': False}
<ul class="errorlist"><li>email<ul class="errorlist"><li>Это поле обязательно.</li></ul></li></ul>
F...
======================================================================
FAIL: test_clean_password (my_auth.tests.test_forms.TestCustomUserChangeForm)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/v-ampire/Projects/django-base/django_base/my_auth/tests/test_forms.py", line 100, in test_clean_password
    self.assertTrue(form.is_valid())
AssertionError: False is not true

I don’t understand, instance is betrayed, shouldn’t username be taken from there?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dr. Bacon, 2020-01-06
@Vampre

When displaying the form, it takes the values ​​​​for the fields from the instance, but when sending a POST request, it must contain at least all the required data, and not just those that have been changed, which you indicated in the error.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question