python自关联_django自关联,auth模块

一、自关联

写蛮好的一篇博客:https://www.cnblogs.com/Kingfan1993/p/9936541.html

1.一对多关联

1.表内自关联是指表内数据相关联的对象和表是相同字段,这样我们就直接用表内关联将外键关联设置成自身表的字段

2.例如,对于微博评论,每条评论都可能有子评论,但每条评论的字段内容应该都是相同的,并且每条评论都只有一个父评论,这就满足了一对多的情形,父评论id为关联字段,可以对应多个子评论

3.外键关联是在子评论中,有关联字段的是子评论,子评论查父评论是正向,父评论查子评论是反向

4.一对多的自关联可以应用在BBS论坛的留言功能中

# models.py中

# 文章表

"""

id title content

1 'hello' 'nihao....'

2 'world' 'shijie....'

"""

class Article(models.Model):

title = models.CharField(max_length=32)

content = models.CharField(max_length=500)

# 评论表

"""

id article_id content reply_id(自关联,作为外键关联自身表的主键id) uid

1 1'cool' 0 (不是任何评论的回复)

21 'hehe' 0

3 1 'wtf' 1 (表示的是这条评论是回复id为1的评论)

4 1 'how' 0

5 2 'haha' 0

6 1 'wow' 1 (也是回复的第一条评论)

7 2 'Um' 5 (回复第五条评论)

8 1 'aha' 3 (回复第三条评论)

"""

class Comment(models.Model):

article = models.ForeignKey("Article")

content = models.CharField(max_length=255)

reply = models.ForeignKey("Comment", default=0)

2.多对多关联

1.例如,建立一张相亲对象表,里面有男有女,我们就可以通过自关联来建立多对多的关系

2.通过ManyToManyField将外键关联自身的主键id

# models.py中

class User(models.Model):

name = models.CharField(max_length=32)

gender_list = [

(1, "男"),

(2, "女"),

]

gender = models.IntegerField(choices=gender_list,default=1)

r = models.ManyToManyField("User")

3.通过python3 manage.py makemigrations和python3 manage.py migrate提交建表模型之后,会生成两个表,一个是主表,另一个是从表

app_user表 和 app_user_r表

4.从表中的的两个字段,一个是 from_主表名_id,一个是 to_主表名_id

5.当我们通过 from_主表名_id 相关联的对象查与 to_主表名_id相关联的对象时,可以直接通过 '主表对象.关系表(从表)' 查询

# views.py中

# 查询和jojo的女生

res = models.User.objects.filter(name='jojo', gender=1).first()

#print(res) # object

objs = res.m.all()

for obj in objs:

print(obj.name)

'''

对应的SQL语句:

1. select * from app01_user_m where from_user_id = 1;

得到的结果就是对应到app_user_r表中的数据时:to_user_id=[3,4] 所对应的对象

2. select * from app01_user where id in (3,4);

'''

6.当我们 通过 to_主表名_id相关联的对象查 from_主表名_id 相关联的对象时,则需要通过 '主表对象.关系表_set' 进行查询

# views.py中

# 查询和 fanbingbing 约会的男生

res = models.User.objects.filter(name='fanbingbing', gender=2).first()

objs = res.user_set.all()

for obj in objs:

print(obj.name)

'''

对应的SQL语句:

1. select * from app01_user_m where to_user_id = 3;

得到的结果就是对应到app_user_r表中的数据时:from_user_id=[1,2] 所对应的对象

2. select * from app01_user where id in (1,2);

'''

二、auth模块

1.auth的简单使用

1.执行数据库迁移的那两条命令时,即使我们没有建表,django是不是也会创建好多张表?我们创建之后去看一下里面的一个叫auth_user表,既然是表,那肯定应该有对应的操作改表的方法

2.auth_user表的记录的添加:创建超级用户,不可以手动插入,因为密码是加密的,手动添加的明文密码没有意义

3.我们可以在pycharm中使用导航栏中的Tools里的run manage.py Task 中输入createsuperuser

# views.py 中

# 就可以使用auth认证了,做一个简单的登陆

from django.contrib import auth

def test(request):

if request.method == "GET":

return render(request,"test.html")

else:

name = request.POST.get("user")

psw = request.POST.get("psw")

myuser = auth.authenticate(request,username=name,password=psw) # 如果auth_user表中有这条记录,则返回一个user对象(一般就是用户名)

if myuser:

auth.login(request,myuser) # 会产生一个user对象,可以在任何视图函数中调用

"""

给当前成功登陆的用户保存登陆状态,之前是通过cookie或者session,现在通过auth;

request.session["name"] = name等价于:auth.login(request,myuser)

"""

return HttpResponse("success")

else:

return redirect("/test/")

# 在其他视图函数中演示

def other(request):

print(request.user)

print(request.user.is_authenticated)

return HttpResponse("ok")

# 总结:

# 1.只要登陆成功执行了auth.login(request,user)

# 之后在其他任意的视图函数中都可以通过request.user获取当前登陆用户对象

# 2.当没有执行auth.login,request.user打印出来的是匿名用户。将session表数据删除即可演示该效果

# 3.如何判断request.user用户是否通过auth.login登陆呢?request.user.is_authenticated,打印:print(request.user.is_authenticated)

# 为何执行auth.login之后,其他视图函数中就可以通过request.user拿到当前登陆对象呢?

# django的中间件中有没有一个叫 'django.contrib.auth.middleware.AuthenticationMiddleware'的中间件,它干了件什么事,能不能推导一下?

# 在web端取出session去django_session表里面查相应的数据

4.注销

auth.logout(request)

# 等价于删除session数据request.session.flush()

2.装饰器

# 装饰器校验是否登陆及跳转

from django.contrib.auth.decorators import login_required

@login_required(login_url='/login/',redirect_field_name='old') # 没登陆会跳转到login页面,并且后面会拼接上你上一次想访问的页面路径/login/?old=/my_view/,可以通过redirect_field_name参数修改next键名(如果不写这个参数,则为127.0.0.1:8090/login/?old=/my_view/,再无啥用了)

def my_view(request):

return HttpResponse("ok")

如果我所有的视图函数都需要装饰并跳转到login页面,那么会很繁琐,我们可以在项目下的settings.py文件中进行配置

# settings.py

# 可以在配置文件中指定auth校验登陆不合法统一跳转到某个路径

LOGIN_URL = '/login/' # 既可以全局配置,也可以局部配置

3.通过auth实现注册功能

1.我们除了通过命令行输入,还可以通过auth提供的其他方法,对auth_user表进行数据的添加

# app的views.py文件中

from django.contrib.auth.models import User

def register(request):

if request.method == "GET":

return render(request, "register.html")

else:

user_name = request.POST.get("username")

psw = request.POST.get("psw")

# User.objects.create() # 不能用这个,因为密码是明文

User.objects.create_user(username=user_name,password=psw) # 创建普通用户

# User.objects.create_superuser(username=user_name,password=psw,email=233@qq.com) # 创建超级用户

4.修改密码

def modify(request):

if request.method=='GET':

return render(request, 'modify.html')

else:

oldpsw = request.POST.get('oldpsw')

newpsw = request.POST.get('newpsw')

res = request.user.check_password(oldpsw) # 获取密码

print(res)

if res:

request.user.set_password(newpsw)

request.user.save()

return HttpResponse('ok')

else:

return render(request, 'modify.html')

5.自定义模型表应用auth功能

1.扩张auth_user表

2.一对一关联(不推荐)

from django.contrib.auth.model s import User

class UserDetail(models.Models):

phone_number = models.CharField(max_length=11)

user = models.OnoToOneField(to=User)

3.面向对象的继承

需要在项目下的settings.py文件中进行配置

# settings.py中

"""

1.指定我不再使用默认的auth_user表而是使用我自己创建的Userinfo表

2.自定义认证系统默认使用的数据表之后,我们就可以像使用默认的auth_user表那样使用我们的UserInfo表了

3.库里面也没有auth_user表了,原来auth表的操作方法,现在全部用自定义的表均可实现

"""

# AUTH_USER_MODEL = "app名.models里面对应的模型表名"

AUTH_USER_MODEL = "app01.User"

就可以在app下的models.py文件中创建我们自己的用户信息表了

# models.py中

from django.contrib.auth.models import User,AbstractUser

# 继承了auth中的user表

class UserInfo(AbstractUser):

phone_number = models.CharField(max_length=32)

6.总结

1.auth登录

obj = auth.authenticate(username, password)

if obj:

auth.login(request, obj)

2.业务逻辑函数验证:

- request.user.is_authenticated()

- from django.contrib.auth.decorators import login_required

@login_required()

3.auth注册:

本质就是向auth_user表添加数据

- createsuperuser

- models.User.objects.create_user()

- models.User.objects.create_superuser()

4.auth的密码更该:

auth.checkpassword() : 验证原来的密码是否正确

auth.setpassword() : 设置新的密码

auth.save()

5.注销(登出)

auth.logout(request)

本质上就是删除django_session中所对应的的记录

6.auth_user表的扩展:

- onetoonefield

- 继承子 AbstractUser 类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值