form.is_valid() всегда возвращает False в Django

У меня появился странный баг. Я не прохожу проверку, если добавляю поле электронной почты. Если валидация только для 1 поля имени пользователя, то все работает нормально. Подскажите пожалуйста, что я делаю не так?

файл forms.py:

class UserUpdateForm(forms.ModelForm):
    email = forms.EmailField(required=False)


    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(UserUpdateForm, self).__init__(*args, **kwargs)
        if 'label_suffix' not in kwargs:
            kwargs['label_suffix'] = '*'
        self.fields['username'].widget = forms.TextInput(attrs={'class':'input-text'})
        self.fields['email'].widget = forms.EmailInput(attrs={'class':'input-text'})


    class Meta:
        model = User
        fields = ("username","email",)

файл views.py:

def get_context_data(self, request):
    self.object = get_object_or_404(Profile,slug=self.kwargs['slug'])
    ctx={}
    ctx['UserUpdateForm']=UserUpdateForm(request.POST if "UserUpdateForm" in request.POST else None,instance=request.user)           
    сtx['comments']=Comments.objects.filter(profile=self.object)
    return ctx

def post(self, request, *args, **kwargs):
    if request.method=='POST':
        if "UserUpdateForm" in request.POST:
            form=UserUpdateForm(request.POST)
            if form.is_valid():
                user=User.objects.get(username=self.request.user)
                user.username=form.cleaned_data.get('username')
                user.email=form.cleaned_data.get('email')
                user.save()
                obj=Profile.objects.get(user__username=user.username)
                return HttpResponseRedirect(reverse_lazy('profile',kwargs={'slug': obj.slug},))
    return render(request,self.template_name,self.get_context_data(request))

person Max    schedule 16.10.2020    source источник
comment
проверьте, что print(form.errors) регистрирует. вы можете добавить это в функцию сообщения или в шаблон {{form.errors}} в вашем шаблоне   -  person hansTheFranz    schedule 16.10.2020
comment
@hansTheFranz: здесь это не сработает, так как форма считается неограниченной. Данные request.POST передаются параметру user, а не параметру данных.   -  person Willem Van Onsem    schedule 16.10.2020


Ответы (1)


Вы создаете форму с дополнительным параметром user:

class UserUpdateForm(forms.ModelForm):
    
    def __init__(self, user, *args, **kwargs):
        # …

так что это означает, что первым параметром при создании формы является пользователь. Таким образом, вы должны передать пользователя:

form=UserUpdateForm(request.user, request.POST)

или если вы хотите отредактировать пользовательский объект:

form=UserUpdateForm(request.user, request.POST, instance=request.user)

однако нет особого смысла передавать пользователя, поскольку, насколько можно видеть, вы никогда не используете атрибут .user в своей форме.

person Willem Van Onsem    schedule 16.10.2020
comment
О, я забыл удалить пользователя. Короче говоря, валидация работает для меня, если меняется имя пользователя и электронная почта. Но если я только сменю почту, валидация не работает, почему? - person Max; 16.10.2020
comment
Я использовал print (form.errors) и получил следующее: ‹ul class=errorlist›‹li›username‹ul class=errorlist›‹li›Пользователь с таким именем уже существует.‹/li›‹/ul›‹/ li›‹/ul› , а как тогда поменять только почту? - person Max; 16.10.2020
comment
@Max: ты работал с instance=request.user? Если вы не используете instance=..., вы создаете нового пользователя, и он, конечно же, будет конфликтовать с существующим. - person Willem Van Onsem; 16.10.2020
comment
Как я могу тогда получить данные для зарегистрированного пользователя? Или просто создать новую форму, только для почты? - person Max; 16.10.2020
comment
@Max: вы используете instance=request.user при построении файла fom. Как в запросе GET, так и в POST. Учтите, что данные старой формы в GET теряются, в POST-запросе вы делаете новый запрос. - person Willem Van Onsem; 16.10.2020
comment
Это не должно решаться. Когда я отправляю форму, я иду прямо к публикации, и там я создаю объект формы с request.POST и сразу же пытаюсь проверить его. Но это не сработает, потому что я не менял имя пользователя и оно такое же, я должен как-то сделать исключение для self.request.user == form.cleaned_data.get('username'), но я могу' т сделать это. Возможно, мне следует создать отдельный метод для проверки данных из формы и текущего пользователя. Если form.is_valid() или self.check_mail(self,form.cleaned_data.get('username')) примерно так. Что вы думаете об этой идее? - person Max; 16.10.2020
comment
@Max: ну, форма работает не так. В этом случае вы должны добавить дополнительную логику, которая проверяет, существует ли уже имя пользователя в request.POST['username']. Если это не так, вы передаете None экземпляру. Но это также усложнило бы такие манеры, как создание пароля и т. д. - person Willem Van Onsem; 16.10.2020