Django form.is_valid не работает и не сохраняет форму

Моя модель аккаунта автоматически создается, когда пользователь создает новый аккаунт & в эту модель добавляется только значение пользователя, остальное остается пустым! Я пытаюсь заставить пользователя обновить или добавить больше информации в модель аккаунта, но is.valid() не работает в представлениях & не сохраняет форму. что пошло не так & как это исправить?

#model.py
class profile(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    bio = models.TextField(blank=True, null=True, max_length=100)
    profile_img = models.ImageField(
        upload_to="profile_images", default="default.jpg")
    location = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return self.user.username
#form.py
class accountForm(ModelForm):
    class Meta:
        model = profile
        fields = "__all__"
        widgets = {
            # 'fields': forms.TextInput(attrs={'class': "form-control"}),
            'profile_img': forms.FileInput(attrs={'class': 'form-control', 'id': 'inputGroupFile04'}),
            'bio': forms.Textarea(attrs={'class': 'form-control'}),
            'location': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Location'}),

        }
#views.py
def account(request):
    Profile = profile.objects.get(user=request.user)
    form = accountForm(instance=Profile)
    if request.method == "POST":
        form = accountForm(request.POST, instance=Profile)
        if form.is_valid():
            form.save()
            return redirect("sign_in")

    context = {"form": form}
    return render(request, "account.html", context)

Я бы внедрил некоторую обработку ошибок в ваше представление. У вас есть

if form.is_valid: но не больше. Поэтому ошибки не отображаются на странице

Обычно, когда это происходит со мной, я бросаю отладочный оператор сразу после вызова .is_valid()

import ipdb; ipdb.set_trace()

Затем в полученном терминале я наберу form.errors и вы увидите, что пошло не так

Во-первых, чтобы загрузить файлы, вам нужно убедиться, что ваш элемент правильно определяет enctype как "multipart/form-data" в теге формы:

#templates file
<form enctype="multipart/form-data" method="post" action="/foo/">

Во-вторых, добавьте request.FILES в form = accountForm(request.POST, request.FILES, instance=Profile)

Подробнее об этом вы можете прочитать в django docs

Для сохранения формы можно использовать cleaned_data.

Попробуйте этот вид:

views.py


def account(request):
    profile_instance = profile.objects.get(user=request.user)
    form = accountForm(instance=profile_instance)
    if request.method == "POST":
        form = accountForm(request.POST, instance=profile_instance)
        if form.is_valid():
            user = request.user
            bio = request.POST.get('bio')
            profile_img = request.POST.get('profile_img')
            location = request.POST.get('location')

            profile.objects.create(
                user=user, bio=bio, profile_img=profile_img, location=location)
            return redirect("sign_in")
    else:
        form = accountForm()

    return render(request, "home/account.html", {'form': form})

Note: Модели пишутся PascalCase, а не smallcase, поэтому будет лучше, если вы назовете ее Profile вместо profile. То же самое касается форм, лучше, если вы напишите AccountForm, или еще лучше ProfileForm вместо accountForm.

Спасибо всем за предложения, но я понял, в чем проблема. Извините, что не предоставил html-коды, потому что я не добавил туда тег forms.user. Поэтому request.POST не предоставлял пользователя. Есть два способа исправить это. Вы можете использовать отношение onetoone в models.py, что не обязательно потребует выбора пользователей. Следующий способ более эффективен, а именно, в forms.py скрыть форму пользователя по:

class accountForm(ModelForm):
    class Meta:
        model = profile
        fields = "__all__"
        widgets = {
            user': forms.hiddenInput(),
            'profile_img': forms.FileInput(attrs={'class': 'form-control', 'id': 'inputGroupFile04'}),
            'bio': forms.Textarea(attrs={'class': 'form-control'}),
            'location': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Location'}),

        }

затем, добавьте пользователя в views.py через INITIAL следующим образом :

def account(request):
    form = accountForm(initial=request.user)
    if request.method == "POST":
        form = accountForm(request.POST, initial = request.user)
        if form.is_valid():
            form.save()
            return redirect("sign_in")

    context = {"form": form}
    return render(request, "account.html", context)

если вы хотите обновить его, используйте instance вместо initial & предоставьте профиль там

Вернуться на верх