2018-04-28

django初级应用

一.实现在浏览器中输入内容,跳转拓展页面继续输入下一个内容, 然后提交到数据库,再从数据库中获得数据显示在浏览器中

1)配置:
Django初始化.png

添加app='stu',修改路由

(?P<stu_id>):
(?P<name>...) 子串匹配到的内容将可以用命名的name来提取url中的值。组的name必须是有效的python标识符,而且在本表达式内不重名。

工程路由,添加路由stu:
image.png

app路由,添加路由addstu:
image.png

2)models.py创建数据表

db_table 用来给表命名

from django.db import models

# Create your models here.


class Student(models.Model):

    s_name = models.CharField(max_length=10)
    s_tel = models.CharField(max_length=11)


    class Meta:
        db_table = 'day51_student'


class StudentInfo(models.Model):
    i_addr = models.CharField(max_length=30)
    s = models.OneToOneField(Student)

    class Meta:
        db_table = 'day51_stuedentinfo'

3) templates书写addStu.html

实现浏览器的输入,提交
form表单中写入路径action, 提交方法method;提交按钮的type类型为submit

<form action="" method="POST">
    <table>
        <tr>
            <th>姓名</th>
            <th>电话</th>
        </tr>
        <tr>
            <td>
                <input type="text" name="name">
            </td>
            <td>
                <input type="text" name="tel">
            </td>
        </tr>
        <tr>
            <td>
                <input type="submit" value="提交">
            </td>
        </tr>
    </table>
</form>

4)views.py写addStu方法

request.method :请求的方法;
GET:获得请求, POST:提交请求

敲黑板: reverse函数在pycharm中不能直接使用alt + enter导入,需要手动导入:from django.core.urlresolvers import reverse,用来实现跳转到指定页面

render与redict区别:
HttpResponseRediect函数:return rediect('/login.html/'):执行的的是url里面的函数,相当于又一次调用新的函数,/login.html/函数里面的所有代码都会执行,并且路径也会改变,用户再次刷新的时候不会改变
render:return render(request,'addStu.html'):只是跳到login.html这个页面上去,没有别的任何操作,和url里的调用都不执行,并且路径还是原来的路径,
当用户再次刷新时,会会重新回到原来路径下的页面

from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from django.core.urlresolvers import reverse
# Create your views here.
from stu.models import Student, StudentInfo

def addStu(request):

    if request.method == 'GET':
        return render(request, 'addStu.html') #跳转到addStu.html页面中

    if request.method == 'POST':
        # 跳转到学习详情页面
        name = request.POST.get('name')#获得POST请求携带的内容,数据存在form date中
        tel = request.POST.get('tel')
# 在数据库中创建相应数据
        stu = Student.objects.create(
            s_name=name,
            s_tel=tel
        )
# 跳转到下一个页面
        return HttpResponseRedirect(
# 路径别名's:red', 传入可变的参数字典 kwargs = {'stu_id':stu.id}
# 因为路径是可变的,所以需要使用别名
# stu.id 为数据中创建数据的id
            reverse('s:red', kwargs={'stu_id': stu.id})
        )

5)学生拓展表studentinfo,书写addStudentInfo方法

# 传入网址上提取到的url(stu_id)变量
def addStuInfo(request, stu_id):

    if request.method == 'GET':
        # GET请求,跳转到指定的html页面
        return render(request, 'addStuInfo.html', {'stu_id': stu_id})

    if request.method == 'POST':
        stu_id = request.POST.get('stu_id')
        addr = request.POST.get('addr')

        StudentInfo.objects.create(i_addr=addr, s_id=stu_id)
        # 提交完毕后返回首页
        return HttpResponseRedirect('/stu/index/')

6)书写studentinfo.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="POST">
    <input type="hidden" value="{{ stu_id }}" name="stu_id">
    地址:<input type="text" name="addr">
    <input type="submit" value="提交">
</form>
</body>
</html>

7)定义首页index.html

</head>
<body>
{% for stuinfo in stuinfos %}
{# 第一次首页的时候, 数据库中没有数据, 添加完毕后, 数据中则有数据,从数据库中取出相应的数据#}
    姓名: {{ stuinfo.s.s_name }}
    电话: {{ stuinfo.s.s_tel }}
    地址: {{ stuinfo.i_addr }}
{% endfor %}

<h4>--------------------------------------</h4>
<a href="{% url 's:add' %}">添加学生</a>
</body>
</html>

二. 实现浏览器登入登出,cookie的使用

登入:查询数据库有没有改用户,没有的话就跳转到注册regist页面,有就进入login页面, 再次刷新的时候需要重新登录
登出: 注册掉数据库相关数据

1)准备:采用第一个项目里的template数据,新建app:uauth

工程urls:python url(r'^uauth/', include('uauth.urls'))
app urls:

image.png

2)创建对应的数据库表

ticket 随浏览器走

from django.db import models

# Create your models here.

class Users(models.Model):
    u_name = models.CharField(max_length=10)
    u_password = models.CharField(max_length=255)
    u_ticket = models.CharField(max_length=30, null=True)


    class Meta:
        db_table = 'day51_user'

3)书写regist, login , logout相应方法

  • regist

密码加密:make_password()
密码解密:check_password()

from django.contrib.auth.hashers import make_password,check_password
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from django.core.urlresolvers import reverse
# Create your views here.
from uauth.models import Users


def regist(request):
    if request.method == 'GET':
        return render(request, 'register.html')

    if request.method == 'POST':
        # 注册
        name = request.POST.get('name')
        password = request.POST.get('password')

        password = make_password(password)

        Users.objects.create(u_name=name,u_password=password)

        return HttpResponseRedirect('/uauth/login/')
  • login

拓展 Httpresponse.set_cookie
HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)

  • 设置一个Cookie。参数与Python 标准库中的 Morsel Cookie 对象相同。
    key:键名,字符串形式。
  • value:对应的值,字符串形式。
  • max_age:cookie 过期的相对时间,单位是秒。如果为None,则当浏览器关闭的时候过期。如果设置了 max_age 而没有设置 expires,则 expires 将根据 max_age 的值计算出来。
  • expires:设置 cookie 过期的绝对时间。应该是一个 UTC "Wdy, DD-Mon-YY HH:MM:SS GMT" 格式的字符串,或者一个 datetime.datetime 对象。如果 expires 是一个datetime 对象,则 max_age 会通过计算得到。
  • path:一个字符串,表示客户端回送 cookie 的路径,如果为‘/’,则表示该域名下的所以路径都将回送 cookie,如果是‘/blog/’;则在访问‘/blog/abc’或者‘/blog/def’等,所有包含该前缀的路径时,客户端都会回送 cookie。
  • domain:cookie有效的域。例如,其值为‘.scolia.com’时,那么在访问 www.scolia.com 或者 test.scolia.com 之类的时,都会回送 cookie ,当然通常会和 path 配合在一起使用。根据 HTTP 协议的要求,这个值必要要两到三个句点,从而防止出现 ‘.com’、‘.edu’、‘va.us’等形式的域名。当域为高层域时,只要两个句点就可以了,而高层域包括:.com、.edu、.net、.org、.gov、.mil、.int、.biz、.info、.name、 .museum、.coop、.aero、和.pro。其他的域则需要至少三个。
  • secure:当其为 True 时,表示只要在 https 连接的情况下才会回送cookie
    httponly:当其为 True 时,JavaScript 等就不能访问对应的cookie了。当然这个标记并不是cookie标准中的,但目前市面上常用的浏览器都支持。灵活使用可以提供数据的安全性。
    注意:
  • RFC 2109 和RFC 6265 都声明客户端至少应该支持 4096 个字节的Cookie。对于许多浏览器,这也是最大的大小。如果视图存储大于 4096 个字节的 Cookie,Django 不会引发异常,但是浏览器将不能正确设置 Cookie。
def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')

    if request.method == 'POST':
        # 如果登录成功,绑定参数到cookie中,set_cookie
        name = request.POST.get('name')
        password = request.POST.get('password')

        if Users.objects.filter(u_name=name).exists():
            user = Users.objects.get(u_name=name)
            if check_password(password, user.u_password):
                ticket = 'agdoajbfjad'
                # 绑定令牌到cookie里面
                response = HttpResponse()
#response返回的是<HttpResponse status_code=200, "text/html; charset=utf-8">
                response.set_cookie('ticket', ticket)
                # 存在服务端
                user.u_ticket = ticket
                user.save()
                return response
            else:
                return HttpResponse('用户密码错误')
        else:
            return HttpResponse('用户不存在')
  • logout

删除cookie
HttpResponse.delete_cookie(key, path='/', domain=None)
cookie中删除指定的 key 及其对应的 value。如果 key 不存在则什么也不发生,也就是不会引发异常。
  由于 Cookie 的工作方式,path 和 domain 应该与 set_cookie() 中使用的值相同 —— 否则 Cookie 不会删掉。

def logout(request):
    if request.method == 'GET':
        response = HttpResponse()
        response.delete_cookie('ticket')
        return HttpResponseRedirect('/uauth/login/')

4)书写相应的html文件

  • register注册
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
</head>
<body>
<form action="" method="POST">
    注册姓名:<input type="text" name="name">
    注册密码:<input type="password" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>
  • login 登录
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<form action="" method="POST">
    登录姓名:<input type="text" name="name">
    登录密码:<input type="password" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>

5)书写首页index.html

实现登陆后跳转到指定页面,没登录跳转到登录页面

def index(request):

    if request.method == 'GET':
        # 获取所有学生信息
        ticket = request.COOKIES.get('ticket')
        if not ticket:
            return HttpResponseRedirect('/uauth/login/')
        if Users.objects.filter(u_ticket=ticket).exists():
            stuinfos = StudentInfo.objects.all()
            return render(request, 'index.html', {'stuinfos': stuinfos})
        else:
            return HttpResponseRedirect('/uauth/login/')

三.零碎的小规模验证应用

1.404 和 500 异常处理

404:主要是代码的错误,导致不能正常打开页面
500:主要是url输入的错误,导致服务出现问题,不能正常打开页面
1)在对应的app中编写错误处理方法

#404
def page_not_found(request):
    return render(request, '404.html')

#500
def server_error(request):
    return render(request, '500.html')

2)书写相应的html文件

404

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>这里是400,400</h1>
</body>
</html>

500

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>500错误页面</title>
</head>
<body>
<h1>这里是500, 500</h1>
</body>
</html>

3)在工程目录下urls导入写入的模块,赋值到相应的错误处理模块上

from stu.views import page_not_found, server_error
handler404 = page_not_found
handler500 = server_error

2.挖坑与填坑

在html文件中,实现内容的重复利用

  • 挖坑:base.html (标题title ---- 内容body)
    方法:{% block title %} {% endblock %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {% block title %} {% endblock %}
    </title>
</head>
<body>
    {% block contains %} {% endblock %}
</body>
</html>
  • 填坑 grade.html
>引用的是base.html中的内容,将grade填掉的内容加入到base中挖掉的内容中
{% extends 'base.html' %}
{% block title %}
    班级列表
{% endblock %}


{% block contains %}
    {% for g in gs %}
        班级ID:{{ g.id }}
        <a href="/s/allstu/{{ g.id }}">
{#        <a href="{% url 's:alls' g.id %} ">#}
            班级名称:{{ g.g_name }}
        </a>
    {% endfor %}
{% endblock %}

3.数据库表的更新与删除(update, delete)

  • 更新
    方法:1-需要手动保存
def upStu(request):
    stu_id = request.GET.get('stu_id')
    stu = Student.objects.get(id=stu_id)
    stu.s_name = '修改的名字'
    stu.save()

方法2:自动保存

def upStu(request):
    stu_id = request.GET.get('stu_id')
    Student.objects.filter(id=stu_id).update(s_name='黄蓉')
    return HttpResponseRedirect('/g/allgrade/')
  • 删除
def delStu(request):

    stu_id = request.GET.get('stu_id')
    Student.objects.filter(id=stu_id).delete()
    return HttpResponseRedirect('/g/allgrade/')

4.关联关系

OnetoOneField:一对一关系
ForeignKey: 一对多关系
ManytoMany: 多对多关系

django目录结构图如下

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容