一对一关系:在Django中将用户模型链接到自定义配置文件模型

本文的翻译是在“ Web开发人员使用Python”课程开始时准备的






PFF ...数据库又来了?







关系数据库中存在三个主要关系:



  • 一对一关系;
  • 一对多关系;
  • 多对多关系。


在本文中,我们将处理第一个关系,即一对一关系。



通常,Django已经具有框架随附的用户模型。它带有自己的字段,方法,属性等。该用户模型的不利之处在于,除了Django中已提供的默认值外,它不允许您添加自定义字段。这可能是一个严重的问题,因为开发人员可能需要从一组经过身份验证的用户中完全配置用户/客户端配置文件。例如,博客站点可能需要作者个人资料,其中将包括用户的照片,联系地址,兴趣爱好,细分市场等。并且Django随附的用户模型不允许这样做。



为了解决此问题,开发人员创建了一个自定义配置文件模型,并使用一对一关系将其连接到Django中的默认用户模型。碰巧的是,保证用户可以连接到一个配置文件,反之亦然。另外,此机制允许更好地控制概要文件模型的定制。



现在,我将向您展示如何在Django中执行此操作。



1.使用默认的Django用户模型。

在要创建配置文件的应用程序中,创建一个新的forms.py文件。在forms.py中,导入以下模块:



from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User


创建一个要继承的类UserCreationForm在此类内,创建另一个具有两个变量的元类:modelfields该变量model将保存您的用户模型,该变量将保存fields将要创建表单字段。



class createUserForm(UserCreationForm):
    class meta:
        model = User
        fields = ['username', 'password1', 'password2']


上面的代码将创建一个表单,其中包含用于用户名,密码和密码确认的字段。



2.创建您的自定义用户配置文件模型。



在您的models.py文件中导入默认用户模型。



from django.contrib.auth.models import User


下一步是创建您自己的配置文件模型,并创建一个与Django中默认用户模型具有一对一关系的用户字段。



class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True,)
    name = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200, null=True)
    address = models.CharField(max_length=200, null=True)

    def __str__(self):
        return self.name


3.为您的轮廓模型创建一个形状。



打开form.py文件,然后从models.py导入您的个人资料模型,还添加一些其他导入,在创建个人资料表单时会派上用场。



from django import forms
from django.utils.translation import ugettext_lazy as _
from .models import Profile


然后创建一个将从继承的类forms.ModelForm在这个类中,创建一个包含两个变量另一元类:modelfields该变量model包含配置文件模型以及fields将要创建的表单字段。



class profileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['name', 'email', 'address']
#The labels attribute is optional. It is used to define the labels of the form fields created   
        labels = {
                "name": _("Name     "),
                "email": _("Email Address"),
                "address": _("Street Address"),
                }


现在已经准备好表单,在将其呈现到模板之前,我们将在views.py中定义逻辑



4.将逻辑添加到views.py



要使用在forms.py中创建的表单,您需要将它们导入到我们的views.py中,并添加一些其他模块,这些模块对于创建逻辑非常有用。



from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login,
from django.contrib import messages
from .models import Profile
from .forms import createUserForm, profileForm


现在让我们创建一个注册页面。让我们将其称为registerPage让我们创建一个空的上下文字典并返回渲染。



def registerPage(request):    
    context = {}
    return render(request, 'app_name/register.html', context)


让我们通过调用POST方法将表单中的值分配给变量。然后,我们将变量传递给上下文字典。



def registerPage(request):
    if request.method == 'POST':
        form = createUserForm(request.POST)
        profile_form = profileForm(request.POST)

    context = {'form': form, 'profile_form': profile_form}
    return render(request, 'app_name/register.html', context)


然后,我们将验证两个表单并保存。



def registerPage(request):
    if request.method == 'POST':
        form = createUserForm(request.POST)
        profile_form = profileForm(request.POST)

        if form.is_valid() and profile_form.is_valid():
            user = form.save()

            #we don't save the profile_form here because we have to first get the value of profile_form, assign the user to the OneToOneField created in models before we now save the profile_form. 

            profile = profile_form.save(commit=False)
            profile.user = user

            profile.save()

    context = {'form': form, 'profile_form': profile_form}
    return render(request, 'app_name/register.html', context)


如果表单值已验证并保存,我们将显示一条成功消息并将用户重定向到登录页面。



def registerPage(request):
    if request.method == 'POST':
        form = createUserForm(request.POST)
        profile_form = profileForm(request.POST)

        if form.is_valid() and profile_form.is_valid():
            user = form.save()

            #we don't save the profile_form here because we have to first get the value of profile_form, assign the user to the OneToOneField created in models before we now save the profile_form. 

            profile = profile_form.save(commit=False)
            profile.user = user

            profile.save()

            messages.success(request,  'Your account has been successfully created')

            return redirect('login')

    context = {'form': form, 'profile_form': profile_form}
    return render(request, 'app_name/register.html', context)


5.渲染模板



在文件中,register.html使用POST方法并action使用空字符串值创建一个表单标签在form标签中csrf_token,我们将其放置为django模板格式,然后我们将动态呈现表单(用户和个人资料表单)。另外,不要忘记提交按钮。



<form method="POST" action="">
                {% csrf_token %}
                    <h3>Register Profile</h3>

                    <div class="form-field">
                        {{profile_form.name.label_tag}}
                        {{profile_form.name}}
                    </div>
                    <div class="form-field">
                        {{form.username.errors}}
                        {{form.username.label_tag}}
                        {{form.username}}
                    </div>
                    <div class="form-field">
                        {{profile_form.email.label_tag}}
                        {{profile_form.email}}
                    </div>
                    <div class="form-field">
                        {{profile_form.address.label_tag}}
                        {{profile_form.address}}
                    </div>
                    <div class="form-field">
                        {{form.password1.errors}}
                        {{form.password1.label_tag}}
                        {{form.password1}}
                    </div>
                    <div class="form-field">
                        {{form.password2.errors}}
                        {{form.password2.label_tag}}
                        {{form.password2}}
                    </div>

                <hr>
                <input id="form-button" class="btn btn-success btn-block" type="submit" value="Create Profile">
                <br>
                    {{form.non_field_errors}}
                <p>Already have an account? <a href="{% url 'login' %}">Login</a></p>
            </form>


由于填写完表单,对其进行验证并保存之后,我们将重定向至登录页面,因此在登录页面的右下角将显示一条有关操作成功的消息,题词为“没有帐户?注册“



 <form method="POST" action="">
                   ...
                 <hr>
                <input id="form-button" class="btn btn-success btn-block" type="submit" value="Login">
                
                {% for message in messages %}
                <p>{{message}}</p>
                {% endfor %}
                <p>Don't have an account? <a href="{% url 'store:register' %}">Register</a></p>
            </form>


这是您为网站创建配置文件模型的方式,该配置文件模型以一对一关系链接到您的用户模型。








All Articles