csrf与auth初识BBS项目

csrf相关的装饰器

# 与csrf验证相关
# 打开csrf中间件后,方法都需要验证

'''
	打开csrf的中间件之后,有几个方法不验证
	关闭csrf的中间件之后,有几个方法验证
'''
from django.views.decorators.csrf import csrf_exempt,csrf_protect

@csrf_exempt  # 不再检测,局部禁用(前提是全站使用)
@csrf_protect  # 检测,局部使用(前提是全站禁用)
def index(request):
    return render(request, 'index.html')

from django.views import View
from django.utils.decorators import method_decorator


@method_decorator(csrf_exempt, name='get')  # 无效
class Login(View):
    @method_decorator(csrf_exempt)  # 有效
    def dispatch(self, request, *args, **kwargs):
        return super(Login, self).dispatch(request, *args, **kwargs)

    @method_decorator(csrf_exempt)  # 无效
    def get(self, request):
        print('get122222222')
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

Auth模块

Auth模块是Django自带的用户认证模块:

我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。

Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统–auth,它默认使用 auth_user 表来存储用户数据。

# django自带的后台管理系统依赖的就是auth_user表
# 需要在进行数据迁移才能够看到表
# 要想登录django的后台管理系统,必须要创建一个超级用户出来
python manage.py createsuperuser
# 需要输入用户名

Auth

from django.views.decorators.csrf import csrf_exempt, csrf_protect


@csrf_exempt
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user_obj = auth.authenticate(request, username=username, password=password)
        # print(user_obj)
        # print(user_obj.username)
        # print(user_obj.password)
        if user_obj:  # 使用了auth就用一整套
            auth.login(request,user_obj)  # 就相当于保存了用户名id这些
            # 只要用了auth.login就可以在任何方法里通过request.user拿到对象
            return redirect('/home/')

    return render(request, 'login.html')


def home(request):
    print(request.user.username)
    return HttpResponse('home')

方法总结

1. 验证用户名和密码是否正确
# 当用户名和密码错误的时候,返回None
user_obj = auth.authenticate(request, username=username, password=password)
print(user_obj)  # admin------------>__str__

2. 登录之后才能访问
from django.contrib.auth.decorators import login_required
# home函数必须登录之后才能访问?
@login_required(login_url='/xxx/')
def home(request):
    print(request.user.username)

    # 如何判断用户是否登录了?
    print(request.user.is_authenticated()) # True  False

    return HttpResponse('我是home页面')

def register(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 参数验证...
        # 入库
        # User.objects.create(username=username, password=password)  # 不加密

        # User.objects.create_user(username=username, password=password) # 加密的
        # 代码创建超级用户,email必填
        User.objects.create_superuser(username=username, email='123@qq.com', password=password)
        return redirect('/home/')
    return render(request, 'register.html')

扩展默认的auth_user表

# 由于auth_user表是django创建的,后续我们有扩展字段的需求,所以我们对这张表进行扩展
# 如何扩展
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.

# 扩展auth_user表,就必须继承AbstractUser类,不在继承models.Model
class UserInfo(AbstractUser):
    """
        我们在扩展字段的时候,默认的字段我们不要动,只写我们要增加的字段

        注意事项:
            1. 扩展字段的时候,默认的字段不要动,只写自己要增加的字段
            2. 如果你扩展了这张表,那么,auth_user表就不存在了,有的是你自己新建的这张表
            3. 新建出来的这张表里面的字段,有之前auth_user表的所有字段外加自己添加的字段
            4. 需要在配置文件中添加一个变量,告诉django我要用现在新的表替代原来的auth_user表
                AUTH_USER_MODEL = 'app01.UserInfo'
                                    '应用名.类名'
            5. 如果你在扩展这张表之前已经执行了数据库迁移命令,需要从新换库
            6. 如果你已经迁移了,还想扩展,怎么办?
                1. 换库
                2. 删很多应用的migrations文件夹
            7. 得出结论:在执行迁移命令之前就扩展好

    """
    phone = models.CharField(max_length=64)
    avatar = models.CharField(max_length=64)

BBS(仿博客园作业)

"""
	对于任何一个项目来说,最重要的不是业务逻辑,而是表结构的设计,以及表关系的设计
	我们以后拿到一个新的需求的时候,首先考虑的就是表机构和表关系!!!!!!!
"""
# 我们先来分析BBS需要哪些表以及表与表之间的关系!!!
"""
1. 用户表
	扩展auth_user表
	扩展字段
		phone
		avatar
		create_time
		...
	
	和站点表是一对一的关系

2. 站点表
	site_name 站点名称
	site_title 站点标题
	site_style 站点样式

3. 文章表
	 title  文章标题
	 desc 文章摘要
	 content 文章内容
	 create_time 文章发表的时间
	 
	  # 数据库字段设计优化
        up_num = models.BigIntegerField(verbose_name='点赞数',default=0)
        down_num = models.BigIntegerField(verbose_name='点踩数',default=0)
        comment_num = models.BigIntegerField(verbose_name='评论数',default=0)
    
    
	 文章和标签是多对多的关系
	 文章和分类表是一对多的关系
	 站点表和文章表是一对多的关系
	 
	 title  desc  content create_time up_num  down_num  comment_num
	 								2        1			3
	 
	 
	 
4. 文章标签表
	标签名称
	标签表和站点表是一对多的关系

5. 分类表
	分类名称
	分类表和站点表是一对多的关系


6. 点赞点踩表
	谁在什么时间点赞了哪篇文章
	
	user
	article
	is_up 
	create_time
	id    user  article  is_up create_time
	1	  1		1		1
	2     2      1       0
	

7. 评论表comment
	谁在什么时间给哪篇文章评论了什么内容
	user
	artilce
	content
	create_time
	
	id   user   article   content  creare_time    parent_id
	1	 1		1			a		''			
	2    2		1            b		  ''			1
	3    3       1			c			''          2
	parent = models.ForeignKey(to='comment')
	parent = models.ForeignKey(to='self')  # 自关联
	
	
根评论和子评论的概念
	根评论:评论文章的评论
	
	子评论:评论文章的评论的评论
	1. PHP是世界上最好的语言
		1.1  python是最好的
			1.2 java是最好的额
根评论和子评论:一对多			
"""

表结构

from django.db import models

# Create your models here.
"""
先写普通字段
之后再写外键字段
"""
from django.contrib.auth.models import AbstractUser


class UserInfo(AbstractUser):
    phone = models.BigIntegerField(verbose_name='手机号',null=True)
    # 头像
    avatar = models.FileField(upload_to='avatar/',default='avatar/default.png',verbose_name='用户头像')
    """
    给avatar字段传文件对象 该文件会自动存储到avatar文件下 然后avatar字段只保存文件路径avatar/default.png
    """
    create_time = models.DateField(auto_now_add=True)

    blog = models.OneToOneField(to='Blog',null=True)


class Blog(models.Model):
    site_name = models.CharField(verbose_name='站点名称',max_length=32)
    site_title = models.CharField(verbose_name='站点标题',max_length=32)
    # 简单模拟 带你认识样式内部原理的操作
    site_theme = models.CharField(verbose_name='站点样式',max_length=64)  # 存css/js的文件路径


class Category(models.Model):
    name = models.CharField(verbose_name='文章分类',max_length=32)
    blog = models.ForeignKey(to='Blog',null=True)


class Tag(models.Model):
    name = models.CharField(verbose_name='文章标签',max_length=32)
    blog = models.ForeignKey(to='Blog', null=True)


class Article(models.Model):
    title = models.CharField(verbose_name='文章标题',max_length=64)
    desc = models.CharField(verbose_name='文章简介',max_length=255)
    # 文章内容有很多 一般情况下都是使用TextField
    content = models.TextField(verbose_name='文章内容')
    create_time = models.DateField(auto_now_add=True)

    # 数据库字段设计优化
    up_num = models.BigIntegerField(verbose_name='点赞数',default=0)
    down_num = models.BigIntegerField(verbose_name='点踩数',default=0)
    comment_num = models.BigIntegerField(verbose_name='评论数',default=0)

    # 外键字段
    blog = models.ForeignKey(to='Blog', null=True)
    category = models.ForeignKey(to='Category',null=True)
    tags = models.ManyToManyField(to='Tag',
                                  through='Article2Tag',
                                  through_fields=('article','tag')
                                  )


class Article2Tag(models.Model):
    article = models.ForeignKey(to='Article')
    tag = models.ForeignKey(to='Tag')


class UpAndDown(models.Model):
    user = models.ForeignKey(to='UserInfo')
    article = models.ForeignKey(to='Article')
    is_up = models.BooleanField()  # 传布尔值 存0/1


class Comment(models.Model):
    user = models.ForeignKey(to='UserInfo')
    article = models.ForeignKey(to='Article')
    content = models.CharField(verbose_name='评论内容',max_length=255)
    comment_time = models.DateTimeField(verbose_name='评论时间',auto_now_add=True)
    # 自关联
    parent = models.ForeignKey(to='self',null=True)  # 有些评论就是根评论
posted @ 2023-05-10 19:19  橘子熊何妨  阅读(20)  评论(0)    收藏  举报