1

day 75天 bbs 项目第一天 ,auth登陆

 

 

 

from django.db import models

from django.contrib.auth.models import AbstractUser

class UserInfo(AbstractUser):
    '''
    用户表
    '''
    nid  =models.AutoField(primary_key=True)
    phone  =models.CharField(max_length=11,null=True,unique=True)
    avatar = models.FileField(upload_to='avatars/',default='avatars/default.png',verbose_name='头像')
    create_time =models.DateTimeField(auto_now_add=True)
    blog =models.OneToOneField(to='Blog',to_field='nid',null=True)
    def __str__(self):
        return self.username

class Blog(models.Model):
    '''
    博客信息
    '''
    nid =models.AutoField(primary_key=True)
    title =models.CharField(max_length=64)
    site =models.CharField(max_length=32,unique=True)
    theme =models.CharField(max_length=32)

    def __str__(self):
        return self.title


class  Category(models.Model):
    '''
    个人博客文章分类
    '''
    nid =models.AutoField(primary_key=True)
    title =models.CharField(max_length=32)#分类标题
    blog = models.ForeignKey(to ='Blog',to_field='nid')#外键关联博客,一个博客站点可以有多个分类

    def __str__(self):
        return self.title

class Tag(models.Model):
    ''''
    标签
    '''
    nid =models.AutoField(primary_key=True)
    title =models.CharField(max_length=32)
    blog =models.ForeignKey(to='Blog',to_field='nid') #所属博客

    def __str__(self):
        return self.title

class Article(models.Model):
    '''
    文章
    '''
    nid =models.AutoField(primary_key=True)
    title = models.CharField(max_length=50) #文章标题描述
    desc =models.CharField(max_length=255) #文章描述
    create_time =models.DateTimeField()#创建时间

    category = models.ForeignKey(to ='Category',to_field='nid',null=True)
    user = models.ForeignKey(to='UserInfo',to_field='nid')
    tags =models.ManyToManyField( # 中介模型
        to ='Tag',
        through='Article2Tag',
        through_fields=('article','tag')#注意顺序

    )

    def __str__(self):
        return self.title

class ArticleDetail(models.Model):
    '''
    文章详情
    '''
    nid =models.AutoField(primary_key=True)
    content = models.TextField()
    article =models.OneToOneField(to ='Article',to_field='nid')

class Article2Tag(models.Model):
    '''
    文章和标签的多对多关系表
    '''
    nid =models.AutoField(primary_key=True)
    article =models.ForeignKey(to='Article',to_field='nid')
    tag =models.ForeignKey(to ='Tag',to_field='nid')

    class Meta:
        unique_together = (('article','tag'),)

class ArticleUpDown(models.Model):
    '''
    点赞
    '''
    nid= models.AutoField(primary_key=True)
    user =models.ForeignKey(to ='UserInfo',null=True)
    artcle = models.BooleanField(default=True)

    class  Meta:
        unique_together = (('article','user'),)

class Comment(models.Model):
    '''
    评论表
    '''
    nid = models.AutoField(primary_key=True)
    article =models.ForeignKey(to ='Article',to_field='nid')
    user =models.ForeignKey(to ='UserInfo',to_field='nid')
    content =models.CharField(max_length=255)#评论内容
    create_time =models.DateTimeField(auto_now_add=True)
    parent_comment =models.ForeignKey('self',null=True)

    def __str__(self):
        return self.content

 

settings 里配置 

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS=[
    os.path.join(BASE_DIR,'static')
]

# 告诉Djanog 项目用哪张表做认证
AUTH_USER_MODEL='app01.UserInfo'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
    # 'default': {
    #     'ENGINE': 'django.db.backends.sqlite3',
    #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    # },

    'default':{
        'ENGINE':'django.db.backends.mysql',
        'NAME':'day77',
        'USER':'root',
        'PASSWORD':'123456',
        'HOST':'127.0.0.1',
        'PORT':3306,

    }
}

 

init配置文件

import pymysql
pymysql.install_as_MySQLdb()


 

登录配置 

 

from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/',views.login)
]

  

 

login登陆页面 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎登陆</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/mystyle.css">
    #导入bootstrap
</head>
<body>

<div class="container">
    <div class="row">
        <form class="form-horizontal col-md-6 col-md-offset-3 login-form"  >
            {% csrf_token %}    登陆界面的csrf token校验
            <div class="form-group" >
                <label for="inputEmail3" class="col-sm-2  control-label">用户名:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="username" name="username" placeholder="用户名">
                </div>
            </div>
            <div class="form-group">
                <label for="password" class="col-sm-2 control-label">密码</label>
                <div class="col-sm-10">
                    <input type="password" class="form-control" id="password" name="password" placeholder="密码">
                </div>
            </div>
{#            <div class="form-group">#}
{#                <div class="col-sm-offset-2 col-sm-10">#}
{#                    <div class="checkbox">#}
{#                        <label>#}
{#                            <input type="checkbox"> 记住密码#}
{#                        </label>#}
{#                    </div>#}
{#                </div>#}
{#            </div>#}
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type='button' class="btn btn-default" id="login-button">登陆</button>
                    <span class="login-error"></span>
                </div>
            </div>
        </form>
    </div>
</div>

<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>

<script>
    $('#login-button').click(function(){
        // 1.取到用户填写的用户名和密码:-->取input框的值
        var username = $('#username').val();
        var password =$('#password').val();
        //2. 用AJAX 发送到服务器端.
        $.ajax({
            url:'/login/',
            type:'post',
            data:{ 'username':username,
                   'password': password ,
                   'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val()
                 },
            success:function (data) {
                console.log(data);
                if (data.status){
                    //有错误,在页面中提示
                    $(".login-error").text(data.msg)
                }else {
                    //登陆成功
                    location.href = data.msg
                }

            }
        })

    })
})
//当input框获取焦点时将之前的错误信息清空
$("#username,#password") .focus(function () {
//将之前的内容清空
$('.login-error').text('');
})
</script>  
</body>
</html>

  

views文件

 

from django.shortcuts import render,redirect,HttpResponse
from   django.http import JsonResponse
from django.contrib import  auth

# Create your views here.

def login(request):
    # if request.is_ajax():
    if request.method =='POST':
        print(request.POST)

        #初始化一个给ajax返回的数据
        ret ={'status':0,'msg':''}
        #从提交过来的数据中取到用户名和密码
        username =request.POST.get('username')
        pwd =request.POST.get('password')
        #利用auth模块进行验证 导入auth模块
        user = auth.authenticate(username=username, password =pwd)
        if user:
            #用户名密码正确 ,登陆成功.
            #给用户做登陆
            auth.login(request,user)
            ret['msg']='/index/'
            return JsonResponse(ret)
            #跳转到index 界面
        else:
            #用户名密码错误,
            ret['status'] =1
            ret['msg']='用户名或密码错误'
            return JsonResponse(ret)
    return render(request,'login.html'
        )

def index(request):
    return  HttpResponse('ok')

  

 

 

二、生成验证码图片

 

验证码:

1. 验证码要随机生成

  1.如何自己生成一个图片

  2. PIL Pillow  

 

 

views 文件配置

#获取验证码图片的视图
def get_valid_img(request):
    with open( 'valid_code.png','rb') as f :
        data =f.read()
        #自己生成一个图片
        from PIL import Image,ImageDraw,ImageFont
        import random


        #获取随机颜色的函数
        def get_random_color():
            return random.randint(0,255),\
             random.randint(0, 255),\
            random.randint(0, 255),

        #生成一个图片对象
        img_obj = Image.new(
            'RGB',
            (220,35),
            get_random_color()
        )
        #在生成的图片上写字符
        #生成一个画笔对象
        draw_obj =ImageDraw.Draw(img_obj)
        #加载字体文件,得到一个字体对象
        font_obj = ImageFont.truetype("static/font/kumo.ttf",28)
        #循环五次添加随机字符
        valid_code_tmp =[]
        for i in range(5):
            n =str(random.randint(0,9))
            l=chr(random.randint(97,122))
            u=chr(random.randint(65,90))
            tmp = random.choice([n,l,u])
            valid_code_tmp.append(tmp)
            draw_obj.text((20+40*i,0),tmp,fill=get_random_color(),font =font_obj)
        #将生成的图片保存在磁盘上.
        # with open( 's10.png','wb') as f :
        #   img_obj.save(f,"png")
        #     #把刚才生成的图片返回给页面
        # with open('s10.png','rb')as f :
        #     data =f.read()

        #不需要在硬盘上保存文件,直接在内存中加载就可以
        from io import  BytesIO
        io_obj =BytesIO()
        #将生成的图片数据保存在io对象中
        img_obj.save(io_obj,'png')
        #从io对象里面取上一步保存的数据
        data =io_obj.getvalue()
        return HttpResponse(data)

  

Login登陆页面配置

 <div class="form-group">
                <label for="password" class="col-sm-2 control-label">密码</label>
                <div class="col-sm-10">
                    <input type="password" class="form-control" id="password" name="password" placeholder="密码">
                </div>
            </div>

               <div class="form-group">
                <label for="password" class="col-sm-2 control-label">验证码</label>
                <div class="col-sm-10">
                    <input type="text"  name="valid_code" >
                    <img class="valid-img" src="/get_valid_img/" alt="">
                </div>
            </div>

            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type='button' class="btn btn-default" id="login-button">登陆</button>
                    <span class="login-error"></span>
                </div>
            </div>

  

 

 

 

 

老师写的登录view文件

from django.shortcuts import render, redirect, HttpResponse
from django.http import JsonResponse
from django.contrib import auth
# Create your views here.

# VALID_CODE = ""


def login(request):
    # if request.is_ajax():  # 如果是AJAX请求
    if request.method == "POST":
        # 初始化一个给AJAX返回的数据
        ret = {"status": 0, "msg": ""}
        # 从提交过来的数据中 取到用户名和密码
        username = request.POST.get("username")
        pwd = request.POST.get("password")
        valid_code = request.POST.get("valid_code")  # 获取用户填写的验证码
        print(valid_code)
        print("用户输入的验证码".center(120, "="))
        if valid_code and valid_code.upper() == request.session.get("valid_code", "").upper():
            # 验证码正确
            # 利用auth模块做用户名和密码的校验
            user = auth.authenticate(username=username, password=pwd)
            if user:
                # 用户名密码正确
                # 给用户做登录
                auth.login(request, user)
                ret["msg"] = "/index/"
            else:
                # 用户名密码错误
                ret["status"] = 1
                ret["msg"] = "用户名或密码错误!"
        else:
            ret["status"] = 1
            ret["msg"] = "验证码错误"

        return JsonResponse(ret)
    return render(request, "login.html")


def index(request):
    return render(request, "index.html")


# 获取验证码图片的视图
def get_valid_img(request):
    # with open("valid_code.png", "rb") as f:
    #     data = f.read()
    # 自己生成一个图片
    from PIL import Image, ImageDraw, ImageFont
    import random

    # 获取随机颜色的函数
    def get_random_color():
        return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)

    # 生成一个图片对象
    img_obj = Image.new(
        'RGB',
        (220, 35),
        get_random_color()
    )
    # 在生成的图片上写字符
    # 生成一个图片画笔对象
    draw_obj = ImageDraw.Draw(img_obj)
    # 加载字体文件, 得到一个字体对象
    font_obj = ImageFont.truetype("static/font/kumo.ttf", 28)
    # 开始生成随机字符串并且写到图片上
    tmp_list = []
    for i in range(5):
        u = chr(random.randint(65, 90))  # 生成大写字母
        l = chr(random.randint(97, 122))  # 生成小写字母
        n = str(random.randint(0, 9))  # 生成数字,注意要转换成字符串类型

        tmp = random.choice([u, l, n])
        tmp_list.append(tmp)
        draw_obj.text((20+40*i, 0), tmp, fill=get_random_color(), font=font_obj)

    print("".join(tmp_list))
    print("生成的验证码".center(120, "="))
    # 不能保存到全局变量
    # global VALID_CODE
    # VALID_CODE = "".join(tmp_list)

    # 保存到session
    request.session["valid_code"] = "".join(tmp_list)
    # 加干扰线
    # width = 220  # 图片宽度(防止越界)
    # height = 35
    # for i in range(5):
    #     x1 = random.randint(0, width)
    #     x2 = random.randint(0, width)
    #     y1 = random.randint(0, height)
    #     y2 = random.randint(0, height)
    #     draw_obj.line((x1, y1, x2, y2), fill=get_random_color())
    #
    # # 加干扰点
    # for i in range(40):
    #     draw_obj.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color())
    #     x = random.randint(0, width)
    #     y = random.randint(0, height)
    #     draw_obj.arc((x, y, x+4, y+4), 0, 90, fill=get_random_color())

    # 将生成的图片保存在磁盘上
    # with open("s10.png", "wb") as f:
    #     img_obj.save(f, "png")
    # # 把刚才生成的图片返回给页面
    # with open("s10.png", "rb") as f:
    #     data = f.read()

    # 不需要在硬盘上保存文件,直接在内存中加载就可以
    from io import BytesIO
    io_obj = BytesIO()
    # 将生成的图片数据保存在io对象中
    img_obj.save(io_obj, "png")
    # 从io对象里面取上一步保存的数据
    data = io_obj.getvalue()
    return HttpResponse(data)

 

自己写的整个登录界面

 

from django.shortcuts import render,redirect,HttpResponse
from   django.http import JsonResponse
from django.contrib import  auth

# Create your views here.
VALID_CODE=''
def login(request):
    # if request.is_ajax():
    if request.method =='POST':
        print(request.POST)
        #初始化一个给ajax返回的数据
        ret ={'status':0,'msg':''}
        #从提交过来的数据中取到用户名和密码
        username =request.POST.get('username')
        pwd =request.POST.get('password')
        valid_code = request.POST.get('valid_code')#获取用户填写的验证码
        print(valid_code)
        print('用户输入的验证码'.center(120,'='))
        if valid_code.upper() ==request.session["valid_code"].upper():
            #利用auth模块进行验证 导入auth模块
            user = auth.authenticate(username=username, password =pwd)
            if user:
                #用户名密码正确 ,登陆成功.
                #给用户做登陆
                auth.login(request,user)
                ret['msg']='/index/'
                return JsonResponse(ret)
                #跳转到index 界面
            else:
                #用户名密码错误,
                ret['status'] =1
                ret['msg']='用户名或密码错误'
                return JsonResponse(ret)
    return render(request,'login.html'
        )

def index(request):
    return  HttpResponse('ok')

#获取验证码图片的视图
def get_valid_img(request):
    with open( 'valid_code.png','rb') as f :
        data =f.read()
        #自己生成一个图片
        from PIL import Image,ImageDraw,ImageFont
        import random

        #获取随机颜色的函数
        def get_random_color():
            return random.randint(0,255),\
             random.randint(0, 255),\
            random.randint(0, 255),

        #生成一个图片对象
        img_obj = Image.new\
                (
            'RGB',
            (220,35),
            get_random_color()
        )
        #在生成的图片上写字符
        #生成一个画笔对象
        draw_obj =ImageDraw.Draw(img_obj)
        #加载字体文件,得到一个字体对象
        font_obj = ImageFont.truetype("static/font/kumo.ttf",28)
        #循环五次添加随机字符
        valid_code_tmp =[]
        for i in range(5):
            n =str(random.randint(0,9))
            l=chr(random.randint(97,122))
            u=chr(random.randint(65,90))
            tmp = random.choice([n,l,u])
            valid_code_tmp.append(tmp)
            draw_obj.text((20+40*i,0),tmp,fill=get_random_color(),font =font_obj)

        print("".join(valid_code_tmp))
        print("生成的验证码".center(120, "="))
            # 不能保存到全局变量
            # global VALID_CODE
            # VALID_CODE = "".join(tmp_list)
            # 保存到session
        request.session["valid_code"] = "".join(valid_code_tmp)

        #将生成的图片保存在磁盘上.
        # with open( 's10.png','wb') as f :
        #   img_obj.save(f,"png")
        #     #把刚才生成的图片返回给页面
        # with open('s10.png','rb')as f :
        #     data =f.read()

        #不需要在硬盘上保存文件,直接在内存中加载就可以
        from io import  BytesIO
        io_obj =BytesIO()
        #将生成的图片数据保存在io对象中
        img_obj.save(io_obj,'png')
        #从io对象里面取上一步保存的数据
        data =io_obj.getvalue()
        return HttpResponse(data)

  

 

前端登录

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎登陆</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/mystyle.css">
    #导入bootstrap
</head>
<body>

<div class="container">
    <div class="row">
        <form class="form-horizontal col-md-6 col-md-offset-3 login-form"  >
            {% csrf_token %}
            <div class="form-group" >
                <label for="inputEmail3" class="col-sm-2  control-label">用户名:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="username" name="username" placeholder="用户名">
                </div>
            </div>
            <div class="form-group">
                <label for="password" class="col-sm-2 control-label">密码</label>
                <div class="col-sm-10">
                    <input type="password" class="form-control" id="password" name="password" placeholder="密码">
                </div>
            </div>

               <div class="form-group">
                <label for="password" class="col-sm-2 control-label">验证码</label>
                <div class="col-sm-10">
                    <input type="text"  name="valid_code" id="valid_code" >
                    <img class="valid-img" src="/get_valid_img/" alt="">
                </div>
            </div>

            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type='button' class="btn btn-default" id="login-button">登陆</button>
                    <span class="login-error"></span>
                </div>
            </div>
        </form>
    </div>
</div>

<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>

<script>
    $('#login-button').click(function(){
        // 1.取到用户填写的用户名和密码:-->取input框的值
        var username = $('#username').val();
        var password =$('#password').val();
        var valid_code=$('#valid_code').val();

        //2. 用AJAX 发送到服务器端.
        $.ajax({
            url:'/login/',
            type:'post',
            data:{ 'username':username,
                   'password': password ,
                    'valid_code':valid_code,
                   'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val()
                 },
            success:function (data) {
                console.log(data);
                if (data.status){
                    //有错误,在页面中提示
                    $(".login-error").text(data.msg)
                }else {
                    //登陆成功
                    location.href = data.msg
                }

            }
        })

    })
        //当input框获取焦点时将之前的错误信息清空
    $("#username,#password") .focus(function () {
        //将之前的内容清空
        $('.login-error').text('');
    })

</script>

</body>
</html>

  

 

 

 

 

 

posted @ 2018-05-24 18:25  萌哥-爱学习  阅读(258)  评论(0编辑  收藏  举报