簡體   English   中英

Django 擴展用戶 Model - 從 Model 繼承配置文件表單

[英]Django Extending User Model - Inherit Profile Form from Model

我正在按照 Django 3.1.7 中的教程執行此操作。

我在這里遇到的問題是我被迫在我的個人資料表單定義中重復我的個人資料 Model。

我想在我的 forms.py 中使用 forms.ModelForm 來繼承我的配置文件 Model 並自動生成 ZAC68B623ABFD6A9FE26CE.8 當 forms.py 已經在我的模型中定義時,必須再次拼出所有內容似乎是多余的。 但我不確定如何使用這種架構來做到這一點。

我已經嘗試過這種方法: https://stackoverflow.com/a/2213802/4144483但問題是用戶窗體不完整 - model 用戶不存在“密碼1”和“密碼2”。 這對於用戶注冊來說不是一個好的解決方案。 我似乎一定會以某種方式使用 UserCreationForm 。

#models.py 
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(max_length=500, blank=True)
    location = models.CharField(max_length=30, blank=True)
    birth_date = models.DateField(null=True, blank=True)

@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    instance.profile.save()


#forms.py
rom django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User

class SignUpForm(UserCreationForm):
    birth_date = forms.DateField(help_text='Required. Format: YYYY-MM-DD')

    class Meta:
        model = User
        fields = ('username', 'birth_date', 'password1', 'password2', )



#views.py
from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
from mysite.core.forms import SignUpForm

def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save()
            user.refresh_from_db()  # load the profile instance created by the signal
            user.profile.birth_date = form.cleaned_data.get('birth_date')
            user.save()
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=user.username, password=raw_password)
            login(request, user)
            return redirect('home')
    else:
        form = SignUpForm()
    return render(request, 'signup.html', {'form': form})

我通常像這樣使用 ModelForm 而不是 CreateUserForm 進行 UserRegistration 並在其中添加 password1 和 password2 字段。 另外,我檢查它們是否相同。:

forms.py

class UserRegistrationForm(forms.ModelForm):
    password = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Repeat Password', widget=forms.PasswordInput)
    email = forms.EmailField(label='Email')
    date_of_birth = forms.DateField(widget=forms.widgets.DateInput(attrs={'type': 'date'}))
    class Meta:
        model = User
        fields = ['username', 'first_name', 'last_name', 'email',
                 ] #these ordering will be as follow in html form

    def clean_password2(self):
        cd = self.cleaned_data
        if cd['password'] != cd['password2']:
            raise forms.ValidationError("Passwords don't match")
        return cd['password2']

然后在視圖中,我創建一個用戶和他們的個人資料,並以加密形式保存密碼,並鏈接他們的個人資料。

views.py

def register(request):
    u_form = UserRegistrationForm(data=request.POST or None)
    p_form = ProfileForm(data=request.POST or None, files=request.FILES or None)
    if u_form.is_valid() and p_form.is_valid():
        new_user = u_form.save(commit=False)
        new_user.set_password(u_form.cleaned_data['password']) #this saves password in encrypted form instead of raw password
        new_user.save()
        profile = p_form.save(commit=False)
        profile.user = new_user
        profile.save()
        return render(request, 'accounts/register_done.html', {'new_user': user})
    return render(request, 'accounts/register.html', {'user_form': u_form, 'profile_form':p_form})

您可以根據需要對其進行修改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM