【Django User】Django 中的拓展自定义用户user模型--20230403

文章介绍了在Django中如何自定义User模型,包括扩展字段、管理器注册、设置AUTH_USER_MODEL以及创建和编辑表单。同时,针对自定义User模型后无法登录的问题,提出了两种密码加密方法,一种是在视图中处理,另一种是在表单的clean方法中处理。
摘要由CSDN通过智能技术生成

https://docs.djangoproject.com/zh-hans/4.0/topics/auth/customizing/

SOP:

在这里插入图片描述

实际代码:

1.models.py覆盖User


class User(AbstractUser):
    age = models.IntegerField(verbose_name=('年龄'),blank=True, null=True,)
    mobilenumber = models.CharField(max_length=500,verbose_name=('电话号码'),blank=True, null=True,)
    # userlink =  models.OneToOneField(AbstractUser, on_delete=models.CASCADE, default=None, null=True)

2.admin.py

from django.contrib.auth.admin import UserAdmin
from .models import User

class UserAdmin(admin.ModelAdmin):

    list_display = ('username',)

    ordering = ('username',)
admin.site.register(User, UserAdmin)

3.settings.py


AUTH_USER_MODEL = 'book.User'

4.python manage.py makemigrations, python manage.py migrate

Migrations for 'book':
  book\migrations\0027_auto_20230403_1636.py
    - Alter field age on user
    - Alter field mobilenumber on user

5.admin界面
在这里插入图片描述

6.在模板上可以使用

    {% block permission_block %}
        {% if request.user.is_authenticated %}
        <div class="m-3">
            用户:<span class="text-primary">{{ request.user.username }}</span>&nbsp;&nbsp;
            姓名:<span class="text-primary">{{ request.user.age }}</span>&nbsp;&nbsp;
            角色:<span class="text-primary">{{ request.user.mobilenumber }}</span>&nbsp;&nbsp;
        </div>
        {% endif %}
    {% endblock %}

在这里插入图片描述

前端显示自定义User模型

forms.py

class theUserForm(ModelForm):
    class Meta:
        model = User
        #fields = '__all__'
        fields = ['username','password','dept','age','mobilenumber','role','theUser_status1',]
        exclude = []

        widgets = {
            "password":wid.PasswordInput(render_value = True) # render_value = True显示值
        }

        # labels= {
        #     "theUser_logo":"用户头像",
        #     "theUser_status1":"生效状态",
        #     "theUser_status2":"借订书籍",
        # }

        
    # 循环找到所有的插件,加入css样式,添加 "class": "form-control"
    bootstrap_exclude_fields = []
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 循环ModelForm中的所有字段,给每个字段的插件设置
        for name, field in self.fields.items():
            if name in self.bootstrap_exclude_fields:
                continue
            # class属性追加form-control,其他属性保留
            if field.widget.attrs:
                field.widget.attrs["class"] = field.widget.attrs.get('class','') + ' ' + 'form-control'
            else:
                field.widget.attrs = {
                    "class": "form-control",
                }

View.py增删改查



def theUserlist_show(request,page=1):
    theUserlist = User.objects.all()
    # 添加分页功能
    paginator = Paginator(theUserlist, 5)
    try:
        page_obj = paginator.page(page)
    except PageNotAnInteger:
        # 如果参数page 的数据类型不是整型,就返回第一页数据
        page_obj = paginator.page(1)
    except EmptyPage:
        # 若用户访问的页数大于实际页数,则返回最后一页的数据
        page_obj = paginator.page(paginator.num_pages) 

    return render(request,'theUserlist_show.html',locals())



def theUserlist_new(request):

    if request.method == "GET":
        form = theUserForm()
        return render(request,'theUserlist_new.html',{'form':form})
    
    # 用户POST请求提交数据,需要进行数据校验
    form = theUserForm(data=request.POST,files=request.FILES)
    if form.is_valid():
        # print(form.cleaned_data)
        # 直接保存至数据库
        form.save()
        return redirect("/theUserlist_show/")

    return render(request,'theUserlist_new.html',{'form':form})



def theUserlist_edit(request,id):
    row_obj = User.objects.filter(id=id).first()

    if request.method == "GET":
        form = theUserForm(instance=row_obj)
        # 判断是否存在借订记录
        theUser_fk_theBorrow_fk_theBook = []
        for fk in row_obj.theborrow_set.all():
            booklist = fk.theBorrow_theBook.theBook_name if fk else 'no-data'
            theUser_fk_theBorrow_fk_theBook.append(booklist)
            print(theUser_fk_theBorrow_fk_theBook)
        return render(request,'theUserlist_edit.html',{'form':form,'theUser_fk_theBorrow_fk_theBook':theUser_fk_theBorrow_fk_theBook,})
    
    # 用户POST请求提交数据,需要进行数据校验
    form = theUserForm(data=request.POST,files=request.FILES, instance=row_obj)
    if form.is_valid():
        # print(form.cleaned_data)
        # 直接保存至数据库
        form.save()
        return redirect("/theUserlist_show/")

    return render(request,'theUserlist_edit.html',{'form':form})


def theUserlist_delete(request,id):
    User.objects.get(id=id).delete()
    return redirect("/theUserlist_show/")

在这里插入图片描述
在这里插入图片描述

外键修改

参考文章https://blog.csdn.net/zeaning/article/details/124110291
2个修复方法,只介绍方法1:
方法1:修改django_admin_log,把user_id关联的外键,改成自己定义的扩展User表
方法2:如果不想改,可以在测试环境(或新建个空的数据库),重新执行迁移,然后把新的django_admin_log表,通过数据库复制的方式,覆盖掉现有的django_admin_log表。

1.方法1–找到django_admin_log
在这里插入图片描述
2.方法1–修改user_id的外键
在这里插入图片描述
在这里插入图片描述
3.提交结构更改
在这里插入图片描述
4.拓展的user模型就可以改了。
在这里插入图片描述

自定义User无法登录,因为密码需要加密

1.没有加密的密码是无法登录的。
在这里插入图片描述

2.需要想办法加密。

方法1:处理密码放在form.save()之后,才能user登录。

from django.contrib.auth.hashers import make_password, check_password


def theUserlist_edit(request,id):
    row_obj = User.objects.filter(id=id).first()

    if request.method == "GET":
        form = theUserForm(instance=row_obj)
        # 判断是否存在借订记录
        theUser_fk_theBorrow_fk_theBook = []
        for fk in row_obj.theborrow_set.all():
            booklist = fk.theBorrow_theBook.theBook_name if fk else 'no-data'
            theUser_fk_theBorrow_fk_theBook.append(booklist)
            print(theUser_fk_theBorrow_fk_theBook)
        return render(request,'theUserlist_edit.html',{'form':form,'theUser_fk_theBorrow_fk_theBook':theUser_fk_theBorrow_fk_theBook,})
    
    # 用户POST请求提交数据,需要进行数据校验
    form = theUserForm(data=request.POST,files=request.FILES, instance=row_obj)
    if form.is_valid():
        # print(form.cleaned_data)
        
        # 直接保存至数据库
        form.save()

        # 处理密码,才能user登录。
        username = form.cleaned_data['username']
        some_user = User.objects.filter(username = username).first()
        some_user.password =  make_password(form.cleaned_data['password'])
        some_user.save()

        return redirect("/theUserlist_show/")

    return render(request,'theUserlist_edit.html',{'form':form})

方法2:利用form.py的super().clean()来处理密码加密
form.py

class theUserForm(ModelForm):
    class Meta:
        model = User
        #fields = '__all__'
        fields = ['username','password','dept','age','mobilenumber','role','theUser_status1',]
        exclude = []

        widgets = {
            "password":wid.PasswordInput(render_value = True) # render_value = True显示值
        }

        labels= {
            "username":"用户名",
            "password":"密码",
        }

        
    # 循环找到所有的插件,加入css样式,添加 "class": "form-control"
    bootstrap_exclude_fields = []
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 循环ModelForm中的所有字段,给每个字段的插件设置
        for name, field in self.fields.items():
            if name in self.bootstrap_exclude_fields:
                continue
            # class属性追加form-control,其他属性保留
            if field.widget.attrs:
                field.widget.attrs["class"] = field.widget.attrs.get('class','') + ' ' + 'form-control'
            else:
                field.widget.attrs = {
                    "class": "form-control",
                }


 	# 全局钩子:验证数据并加密数据
    def clean(self):
        # 不能丢
        super().clean()
        pwd=self.cleaned_data.get("password")  
        if pwd:
            self.cleaned_data['password'] = make_password(self.cleaned_data['password'])
        else:  
            return self.cleaned_data

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值