Pff ...データベースをもう一度?
リレーショナルデータベースには、次の3つの主要な関係があります。
- 1対1の関係。
- 1対多の関係。
- 多対多の関係。
この記事では、これらの最初の1対1の関係について説明します。
通常、Djangoにはフレームワークに付属するユーザーモデルがすでにあります。独自のフィールド、メソッド、属性などが付属しています。このユーザーモデルの欠点は、Djangoですでに提供されているデフォルト以外にカスタムフィールドを追加できないことです。開発者は、認証されたユーザーのグループからユーザー/クライアントプロファイルを完全に構成する必要がある場合があるため、これは深刻な問題になる可能性があります。たとえば、ブログサイトには、ユーザーの写真、連絡先アドレス、趣味、ニッチなどを含む作成者プロファイルが必要な場合があります。また、Djangoに付属のユーザーモデルではこれができません。
この問題を解決するために、開発者はカスタムプロファイルモデルを作成し、1対1の関係を使用してDjangoのデフォルトのユーザーモデルに接続します。たまたま、ユーザーは1つのプロファイルに接続されていることが保証されており、その逆も同様です。さらに、このメカニズムにより、プロファイルモデルのカスタマイズをより適切に制御できます。
次に、Djangoでこれを行う方法を説明します。
1.デフォルトのDjangoユーザーモデル
を使用するプロファイルを作成するアプリケーションで、新しいforms.pyファイルを作成します。でforms.py、以下のモジュールをインポートします。
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
から継承するクラスを作成します
UserCreationForm
。このクラス内に、2つの変数を持つ別のメタクラスを作成します: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のデフォルトのユーザーモデルと1対1の関係を持つユーザーフィールドを作成する必要があります。
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
。このクラスで、2つの変数を含む別のメタクラスを作成します: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
し、空の文字列値を使用してフォームタグを作成します。フォームタグ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>
これは、1対1の関係でユーザーモデルにリンクされているサイトのプロファイルモデルを作成する方法です。