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
。在此类内,创建另一个具有两个变量的元类:model
和fields
。该变量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
。在这个类中,创建一个包含两个变量另一元类:model
和fields
。该变量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>
这是您为网站创建配置文件模型的方式,该配置文件模型以一对一关系链接到您的用户模型。