D7 allauth 采坑日记 Extending & Substituting User model (2)

接续上一篇 这次要讲的是我研究中途试过的另一个方法 Substituting
这其实是我一开始的想法
我本来的想法是在auth_user table内新增一个filed 叫做phone_number 如下示意图
Imgur

在网路上查how to customize user form 会给你很多不同的答案而我每一样都是过 但都出现问题
刚好下面这篇列举了3种我遇过的失败
https://stackoverflow.com/questions/64396391/how-am-i-supposed-to-add-a-field-to-a-signup-form-in-django-allauth-docs-vs-sta
第1个失败的原文网址在这
https://dev.to/danielfeldroy/customizing-django-allauth-signup-forms-2o1m
他在setting中把原本allauth的signup form从 allauth/account/forms.py 改成 app/user/forms.py中的SpyBookSignupForm类别
在SpyBookSignupForm类别继承allauth本来的signup form然後再去修改
但是这种方法前提是你要存的type这个栏位已经在auth_user table里面
但他也没有讲model怎麽改才能让auth_user table新增栏位
第2个失败是django作者pennersr给的方法
https://stackoverflow.com/questions/12303478/how-to-customize-user-profile-when-using-django-allauth
这方法其实没错 只是 first_name & last_name本来就是在auth_user table里面有的栏位所以你用以下的code去处理会真的看到资料库有新增first_name & last_name

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

但如果你改成要增加phone_number如下
你确实会在注册画面跳出让你填写Phone number的地方
但当你送出之後资料库里面不会存到phone_number 原因也是auth_user没有phone_number这个栏位(user.phone_number这行就存不到东西)

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')
    phone_number = forms.CharField(max_length=30, label='Phone Number')
    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.phone_number = self.cleaned_data['phone_number']
        user.save()

第3个失败也一样追根究柢是没有phone_number栏位

追来追去我找到这篇
https://stackoverflow.com/questions/54242325/django-all-auth-custom-signup-form-with-custom-user-model
他用继承AbstractUser的方法自行创建一个新的user表 这方法确实有用但是....你的资料库要完全重建才行
因此我开了一个新的专案docsystem_4 新增user_infos app
从现在开始一直到最後都不要执行makemigrations, migrate

因为上一篇讲很多设定了 重复的不分我就不讲 我讲差异点
docsystem_4/settings.py
除了allauth需要的基本参数以及installed_app要改成user_infos之外还要新增一个
他这个会去抓user_infos/models内的User类别

AUTH_USER_MODEL = 'user_infos.User'

docsystem_4/urls.py

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')),
]

user_infos/models.py 改成如下

from django.db import models
from django.contrib.auth.models import User, AbstractUser
from django.utils.translation import gettext_lazy as _

# Custom Usermodel 
class User(AbstractUser):
    phonenumber = models.CharField(_('phonenumber'), max_length=8, blank=True, default="")
    pass

user_infos/forms.py 改成如下

from django import forms

class GuestSignUpForm(forms.Form):
    first_name = forms.CharField(
        max_length=30,
        label="First Name",
        widget=forms.TextInput(
            attrs={"placeholder":"小明"}
        ),
    )
    last_name = forms.CharField(
        max_length=30,
        label="Last Name",
        widget=forms.TextInput(
            attrs={"placeholder":"王"}
        ),
    )
    phonenumber = forms.CharField(
        max_length=10,
        label="Phone number",
        widget=forms.TextInput(
            attrs={"placeholder":"0987654321"}
        ),
        required=False,
    )

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.phonenumber = self.cleaned_data['phonenumber']
        user.save()
        return user

改动其实比上一篇的少
然後执行创建table的步骤

python manage.py makemigrations #告诉django依据model跟installed_app要该栋那些table
python manage.py migrate        #执行以上的变动
python manage.py runserver      #执行server

完成後你的资料表架构变成这样
原本的auth_user变成的user_infos_user 并且出现了phone_number栏位
Imgur
Imgur

这种自行创建的方法好处是可以自行定义user表内要有那些栏位 可以新增可以变动
但是如果本来的资料库就有资料除非你会用SQL语言把资料库备份到新建立的资料库内 不燃你要全部重建资料很麻烦
所以我才会选用上一篇那种扩充的方式来新增table
未来如果要新增我也可以直接用对应的方式去写 更有弹性


<<:  musl libc 简介与其 porting(三)No time to die.

>>:  Day13. class_eval & instance_eval - 解答什麽是 MetaClass & Singleton

转行如何学Python ?

最近在准备转行学python,此前学过一段时间JAVA,想来问问大神们有什么好的资料分享吗?之前在其...

了解内嵌、外嵌导入css方式

进入到css的环节,讲解如何使用内嵌、外嵌导入css的方式 要注意内嵌、外嵌使用方式不太一样 外嵌...

Dart语言和你 SAY HELLO!!

第四天 各位点进来的朋友,你们好阿 小的不才只能做这个系列的文章,但还是希望分享给点进来的朋友,知道...

隐藏&显示画面中间的某区块

缘由: 开发时或多或少会遇到因某个条件地达成,需要显示或隐藏画面中的另一个条件,若是区块在最底部,直...

[Day 5] 站在巨人的肩膀上 - 回顾股票市场交易论文

一、前言 矮子能看得更远,只因为他站在巨人的肩膀上。 - Isaac Newton 今天的文章,我将...