【问题标题】:Django form data isn't saving to databaseDjango 表单数据未保存到数据库
【发布时间】:2019-08-29 06:37:09
【问题描述】:

我正在尝试允许用户使用城市、描述、网站地址等更新他们的用户资料。

使用 Django 2.0,我在一个视图中有两个表单:

EditProfileForm (EPF) = 电子邮件表格、姓名和密码

EditProfileForm 似乎能够保存数据。但是,EditUserProfile 似乎没有。

EditUserProfile (EUP) = 更多用户信息的表单,例如城市、描述、网站地址等。

输入数据并提交表单时,EUP 表单的数据似乎不会保存或更新用户信息

我也试过这样的方法:

if form_EUP.is_valid():
    obj = form_EUP.save(commit=False)
    obj.user = request.user
    obj.save()

并尝试创建与 RegistrationForm 中使用的格式类似的自定义保存方法,但我没有运气

我是 django 框架的初学者,所以任何想法都将不胜感激,干杯。

views.py

def edit_profile(request):
    if request.method == 'POST':
        form_EPF = EditProfileForm(request.POST, instance=request.user)
        form_EUP = EditUserProfile(request.POST, instance=request.user)

        if form_EPF.is_valid():
            form_EPF.save()
            return redirect(reverse('accounts:view_profile'))

        if form_EUP.is_valid():
            form_EUP.save()
            return redirect(reverse('accounts:view_profile'))

    else:
        form_EPF = EditProfileForm(instance=request.user)
        form_EUP = EditUserProfile(instance=request.user)

        args = {'form_EPF': form_EPF, "form_EUP": form_EUP}
        return render(request, 'accounts/edit_profile.html', args)

forms.py


class RegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = (
            'username', 
            'first_name',
            'last_name',
            'email',
            'password1',
            'password2'
            )

    def save(self, commit=True):
        user = super(RegistrationForm, self).save(commit=False)
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.email = self.cleaned_data['email']

        if commit:
            user.save()

        return user

class EditProfileForm(UserChangeForm):

    class Meta:
        model = User
        fields = (
            'email',
            'first_name',
            'last_name',
            'password',
            )

class EditUserProfile(ModelForm):
    description = forms.CharField(required=False)
    city = forms.CharField(required=False)
    website = forms.URLField(required=False)

    class Meta:
        model = UserProfile
        fields = (
            'description',
            'city',
            'website',
            'image',
            )

models.py

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    description = models.CharField(max_length=100, default='')
    city = models.CharField(max_length=100, default='')
    website = models.URLField(default='')
    phone = models.IntegerField(default=0)
    image = models.ImageField(upload_to='profile_image', blank=True)

    def __str__(self):
        return self.user.username

def create_profile(sender, **kwargs):
    if kwargs['created']:
        user_profile = UserProfile.objects.create(user=kwargs['instance'])

post_save.connect(create_profile, sender=User)

edit_profile.html

{% block body %}
<div class="container">
    <h1>Edit profile</h1>
    <form method="post">
        {% csrf_token %}
        {{ form_EPF.as_p }}
        {{ form_EUP.as_p }}
        <button type="submit">Submit</button>
    </form>
</div>
{% endblock %}

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    这里:

        if form_EPF.is_valid():
            form_EPF.save()
            return redirect(reverse('accounts:view_profile')) # !!!!!
    
        if form_EUP.is_valid():
            form_EUP.save()
            return redirect(reverse('accounts:view_profile'))
    

    你是在保存用户表单后返回的,所以配置文件表单确实永远不会保存(除非用户表单无效 xD)。

    你想要:

        if form_EPF.is_valid() and form_EUP.is_valid():
            form_EPF.save()
            form_EUP.save()
            return redirect(reverse('accounts:view_profile')) # !!!!!
    

    另外,你有这个不起作用:

    form_EUP = EditUserProfile(request.POST, instance=request.user)
    

    您传递的是 ̀Userasinstance, but the form expects aUserProfile`。

    而且 - 虽然它不会阻止您的代码运行 - 您肯定要三思而后行命名。 “EditProfileForm”编辑用户,因此它应该真正命名为“EditUserForm”(或“UserEditForm”等),并且您视图中的变量也好不到哪里去 - ̀form_EPFandform_EUPrequires active thinking to parse the suffix and match it with the (already counter-intuitive) form class names, and you _don't_ want to have to do any effort to understand what a name means when reading code. Just use the all_lower form of the class instead, so assumin you renamed your form classes to a much sanerUserEditFormandProfileEditForm@987654329 @user_edit_formandprofile_edit_form`。这确实是额外的几次击键,但平均而言,您阅读代码的时间比编写代码的时间多 1000 倍,因此确实值得优化阅读。

    【讨论】:

    • 干杯,非常感谢!关于变量名的要点非常好,所以我会整理出来。再次感谢!
    猜你喜欢
    • 2021-10-07
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 2018-05-16
    • 2021-06-28
    • 2017-03-06
    • 1970-01-01
    相关资源
    最近更新 更多