Django(5)

5. 视图和模型结合使用

5.1 设计展示用户操作页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="sucess.html">
        输入用户名:<input type="text" name="name" id="name"><br>
        年龄:<input type="text" name="age" id="age"><br>
        电话:<input type="text" name="phone" id="phone"><br>
        <button type="submit">提交</button>
    </form>
</body>
</html>

5.2 设置页面对应的路径,当用户请求的时候,展示

from django.http import HttpResponse
def show(request):

    return render(request,'show.html')

注意点:

  • 必须传入一个参数
  • 返回一个HttpResponse对象

5.3 HTTP请求对象

<WSGIRequest: GET '/showregister'>
  1. 这是一个HTTP请求对象
  2. 这个请求对象里面封装的是请求信息,包括请求的方式,数据

requeset相关属性:

http://127.0.0.1:8000/book/bookinfo10/

描述
path/book/bookinfo10/
5.3.1 request.body

当废表单数据,request.body来获取到请求体数据,但是,body获取的数据是bytes类型

一般情况下是json

5.3.2 request.GET

获取到都是类字典类型-

5.3.3 request.POST

获取到都是类字典类型

5.3.4 request.META 获取请求头数据
print(request.META)
print(request.META['HTTP_USER_AGENT'])

#Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36

5.4 HTTPResponse 对象

5.4.1 render 函数的具体使用
def render(request, template_name, context=None, content_type=None, status=None, using=None):
    """
    Returns a HttpResponse whose content is filled with the result of calling
    django.template.loader.render_to_string() with the passed arguments.
    """
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)

注意点:

  1. render函数适用范围:有网页,有填充网页的数据
  2. render函数的第一个参数:当前路径的请求对象
  3. context:填充网页的数据,格式为字典类型

5.5 路径传参

urls.py中添加

url(r'^(\d+)$',views.bookinfo10),

view.py中添加

def bookinfo10(request,param=None):
    print(param)
    return HttpResponse('测试试试')

绑定参数,关键字传参的问题

url(r'^(?P<param>\d+)/(?P<param2>\w+)$',views.bookinfo10),

view.py中添加

def bookinfo10(request,param2=None,param=None):
    print(request.path)
    print(param)
    print(param2)
    return HttpResponse('测试试试')

5.6 例子

实现:页面出现所有的书籍,在每本书籍的后面两个按钮,一个按钮展开详情页,一个按钮可以删除这本书

view.py文件

def showbookinfo(request):
    # todo 1. 从数据库讲所有的书籍加载出来
    book_obj_list = BookInfo.objects.all().filter(is_delete=False)

    # todo 1.1 将数据拼接上下文
    context = {'data':book_obj_list}

    # todo 2. 将数据传递给前端
    return render(request,'books.html',context)
    # return JsonResponse({"data":"ok"},safe=False)

def deletebook(request,book_id=None):
    # 物理删除 1
    # book = BookInfo.objects.get(id=book_id)
    # book.delete()

    # 物理删除 1
    # book = BookInfo.objects.filter(id=book_id).delete()

    # 逻辑删除
    book = BookInfo.objects.get(id=book_id)
    book.is_delete=1
    book.save()

    book_obj_list = BookInfo.objects.all().filter(is_delete=False)
    context = {'data': book_obj_list}

    # return HttpResponse('okg')
    return render(request, 'books.html',context)

def showbook(request,book_id=None):
    book = BookInfo.objects.get(id=book_id)

    book_obj_list = BookInfo.objects.all().filter(is_delete=False)
    context = {'data': book_obj_list}

    return render(request,'books.html',context)

urls.py文件

url(r'^showbookinfo',views.showbookinfo),
    url(r'^deletebook/(\d+)$',views.deletebook),
    url(r'^showbook/(\d+)$',views.showbook),

books.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        var temp='';
        function showAction(id,xxx,yyy){
            if(temp===""){
                document.getElementById(id).innerHTML=xxx;
                temp = 'show';
            }
            else {
                document.getElementById(id).innerHTML=yyy;
                temp = '';
            }

        }
</script>
</head>
<body>

<ul>
{% for obj in data %}
    <li><span id={{ obj.id }}>{{ obj }}</span><a href="/book/deletebook/{{ obj.id }}"><button>delete</button></a><button onclick="showAction({{ obj.id }},'{{ obj.bookname }}--{{ obj.publictime }}--{{ obj.count }}--{{ obj.seltcount }}','{{ obj }}')">show</button></li>
{% endfor %}
</ul>

</body>
</html>

5.7 前后端分离

from django.http import HttpResponse,JsonResponse

def showbookinfo(request):
    return JsonResponse({"data":"ok"},safe=False)

5.7 关于浏览器与服务器之间的状态保持

5.7.1 cookie

浏览器与服务器之间是无状态的

session:存在服务器一端

cookie:一一对应

特点:

  1. 键值结构
  2. cookie是基于域名安全的,不同域名之间cookie是不可以进行相互访问的
  3. 当浏览器请求某一网站,会将于当前网站所有的cookie提交给服务器
  4. cookie数据不允许存储敏感信息,密码,支付码密码
5.7.2 cookie的设置

创建cookie:cookie是服务器设置,所以返回一个response

def set_cookie(self, key, value='', max_age=None, expires=None, path='/',domain=None, secure=False, httponly=False):
    """
    Sets a cookie.
    ``expires`` can be:
    - a string in the correct format,
    - a naive ``datetime.datetime`` object in UTC,
    - an aware ``datetime.datetime`` object in any time zone.
    If it is a ``datetime.datetime`` object then ``max_age`` will be calculated.
    """
def set_cookies(request):
    response = HttpResponse('设置cookie')
    # def set_cookie(self, key, value='', max_age=None,   max_age的单位是s,如果是临时cookie,设置为None
    response.set_cookie('name1','python')
    response.set_cookie('name2','django',max_age=3600)
    return response

获取cookie:浏览器存在浏览器,获取是通过request

def get_cookies(request):
    print('99999999999999999999999999999999999')
    print(request.COOKIES.get('name1'))
    print(request.COOKIES.get('name2'))
    return HttpResponse('获取cookies')

删除cookie:cookie是服务器设置,需要返回response

def delete_cookies(request):
    response = HttpResponse('删除cookies')
    response.delete_cookie('name1')
    return response

总结:Cookie虽然存储在浏览器一端,但是,它是在服务器一端进行设置的,

5.7.3 session
  1. 需要使用数据库存储session,安装应用

    setting.py

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        # django中session是默认存储在我们的数据库中的,一旦存在数据库中,就需要在INSTALLED_APPS中进行注册
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # 定义子应用
        #'user'
        'user.apps.UserConfig',
        'book.apps.BookConfig',
    ]
    
  2. 在数据库中

    mysql> show tables;
    +----------------------------+
    | Tables_in_pai0805          |
    +----------------------------+
    | auth_group                 |
    | auth_group_permissions     |
    | auth_permission            |
    | auth_user                  |
    | auth_user_groups           |
    | auth_user_user_permissions |
    | bookinfo                   |
    | django_admin_log           |
    | django_content_type        |
    | django_migrations          |
    | django_session             |
    | personinfo                 |
    | user_userinfo              |
    +----------------------------+
    
    mysql> desc django_session;
    +--------------+-------------+------+-----+---------+-------+
    | Field        | Type        | Null | Key | Default | Extra |
    +--------------+-------------+------+-----+---------+-------+
    | session_key  | varchar(40) | NO   | PRI | NULL    |       |
    | session_data | longtext    | NO   |     | NULL    |       |
    | expire_date  | datetime(6) | NO   | MUL | NULL    |       |
    +--------------+-------------+------+-----+---------+-------+
    

    注意:在Django项目中,session的引擎没有设置,则是默认的存储方式

5.7.4 session的安装配置
  1. 第一种方式:存储在本地缓存

    # 设置session存储在本地缓存
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
    # 缺点:如果丢失不能找回
    # 优点:比数据库读写快
    
  2. 第二种方式:混合存储

    # 混合存储:内存和数据库混合存储
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache_db'
    # 优先从本机内存中,存取,如果没有,从数据库存取
    
  3. 第三种方式:存在redis非关系性数据库中

    # 存在redis非关系性数据库中
    # 1. 安装第三方扩展
    #  pip install django-redis
    
    # 2. 配置redis
    
    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100}
                # "PASSWORD": "123",
            }
        }
    }
    
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
    SESSION_CACHE_ALIAS = 'default'
    # SESSION_COOKIE_AGE = 60 * 5    #设置5分钟过期,不设置用系统默认
    
    # 3. 绑定ip地址
    # sudo vi/etc/redis/redis.conf
    
    # 4. 重启redis服务
    # sudo service redis-server restart
    
5.7.5 session的设置

设置session

def set_session(request):
    request.session['session1'] = 'hello'
    return HttpResponse('设置session')

获取session

def get_session(request):
    print(request.session.get('session1'))
    # 清空所有的session值
    request.session.clear()
    # 删除 整条数据
    request.session.flush()
    # 删除 指定的数据
    del request.seseion['sess1']
    return HttpResponse('得到session')

5.8 中间件的使用

5.8.1 创建一个中间件

user文件夹中创建middleware.py文件

def my_middle(get_request):
    print('init开始被调用')
    def middileware(request):
        print('before requst被调用')
        reponse = get_request(request)
        print('after reponse被调用')
        return reponse
    return middileware
5.8.2 注册进settings文件中
# 中间件
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 默认开始csrf的校验
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'user.middleware.my_middle', # 注册中间件
]
5.8.3 多个中间件的顺序
# 中间件
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 默认开始csrf的校验
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'user.middleware.my_middle', # 注册中间件
]

在请求视图被处理之前,中间件的顺序自上而下

在请求视图被处理之后,中间件的顺序自下而上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值