如何使用 OnetoOneField 扩展用户模型制作用户配置文件表单?

时间:2021-01-16 00:49:40

标签: django

我想制作一个使用 OnetoOneField 扩展用户模型的表单。它基本上是一种用户可以在注册后添加/更新他们的信息的形式。

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    username = models.CharField(max_length=120)
    name = models.CharField(max_length=120)  # max_length = required
    email = models.EmailField(max_length=120)
    paypal_id = models.CharField(max_length=120)
    bio = models.TextField(max_length=500, blank=True)

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

forms.py

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ["username", "name", "email", "paypal_id", "bio"]

views.py

def userprofile_view(request):
    if request.method == 'POST':
        profile_form = UserProfileForm(request.POST)

        if profile_form.is_valid():
            profile = profile_form.save(commit=False)
            profile.save()

            return redirect('account')
    else:
        profile_form = UserProfileForm()

    context = {'profile_form': profile_form}
    return render(request, 'accounts/account_create.html', context)

模板.html

{% extends 'base.html' %}

{% block content %}    
<form action="." method="POST">
    {% csrf_token %}
    {{ profile_form.as_p }}
    <input type="submit" value="Save"/>
</form>
{% endblock %}

我点击保存时不断收到此错误:

<块引用>

(1048, "列 'user_id' 不能为空")

有没有办法解决这个问题?

2 个答案:

答案 0 :(得分:0)

您可以使用通用创建视图同时创建用户和配置文件模型。

表格:

class UserProfileForm(forms.ModelForm):
class Meta:
    model = Profile
    fields = ["username", "name", "email", "paypal_id", "bio", "user"]

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

class Meta:
    model = User
    fields = ['username', 'first_name', 'last_name', 'email', 'password1', 'password2']

查看:

class CreateUserProfileView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
model = Profile
form_class = UserProfileForm
user_form_class = UserForm
template_name = 'accounts/account_create.html'
success_message = "Profile created successfully"
success_url = reverse_lazy('profile-list')

def get(self, request):
    profile_form = self.form_class()
    user_form = self.user_form_class()
    return render(request, self.template_name, {'profile_form': profile_form, 'user_form': user_form})

def post(self, request, *args, **kwargs):
    profile_form = self.form_class(request.POST)
    user_form = self.user_form_class(request.POST)
    if all([profile_form.is_valid(), user_form.is_valid()]):
        user = user_form.save()
        profile = profile_form.save(commit=False)
        profile.user = user
        profile.save()
        messages.success(request, self.success_message)
    else:
        return render(request, self.template_name, {'profile_form': profile_form, 'user_form': user_form})

    return HttpResponseRedirect(self.success_url)

答案 1 :(得分:0)

您需要覆盖 Profile 的 save() 方法以在保存 Profile 时即时创建/更新用户。

即:

class Profile(models.Model):

...

    def save(self, *args, **kwargs):

        if not self.user.pk:
            self.user = User.objects.create_user(self.user.username, password=self.user.password)

        self.user.save()  # mandatory as create_user is not recognized as save operation
        super().save(*args, **kwargs)