文章目录

  • 一、Django 请求
  • (一)常见的请求方式
  • (二)请求状态码
  • (三)Django请求对象
  • 二、Django表单
  • 1、定义数据库模型
  • 2、前端构建表单
  • 3、后端接收保存数据
  • 三、Django CSRF
  • 在表单当中添加csrf的方法:
  • 四、Django后端表单校验
  • (一)表单类
  • (二)校验的流程
  • (三)自定义校验
  • 五、Django会话技术
  • (一)cookie操作
  • 1. 设置
  • 2. 获取
  • 3. 删除
  • (二)session操作
  • 1. 设置
  • 2. 获取
  • 3. 删除


一、Django 请求

from表单 是前端的知识点,和后端没有很大的关系,无论哪门语言作为后端,前端是一致的:

action 表单数据提交到的路径

method 提交的方式

enctype 提交数据的类型,针对文件(图片)

name 所有表单元素的单词。

(一)常见的请求方式

默认页面请求都是GET请求。
视图函数中request是传递到视图的请求,里面包含请求的各种参数。

常用的请求方式get和post:

  1. get:默认是get请求,请求数据以明文形式放在路由上,get的格式是以?开头,键值对形式,以&分割键值对,通常用于向服务器获取资源。
  2. post:请求数据隐藏发送,安全系数更高。通常用于向服务器提交资源。

其他请求还有:PUT、DELETE、OPTION

(二)请求状态码

200:(成功) 服务器已成功处理了请求。
300:(重定向) 表示要完成请求,需要进一步操作。
400:(请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
500:(服务器错误)表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。

上述知识点属于前端和HTTP协议,是所有web开发共性知识。部分需要特殊掌握。

(三)Django请求对象

Django通过视图函数定义的第一个参数来接收请求,接收到是WSGIRequest对象,里面包含了整个请求所有的参数,常用的:

参数

描述

request.GET

接收get请求的参数

request.POST

接收post请求的参数

request.FILES

接收文件数据

request.method

请求方式

request.META

请求的细节参数

request.META.OS

请求的系统类型

request.META.HTTP_USER_AGENT

请求的浏览器版本

request.META.HTTP_HOST

主机地址

request.META.HTTP_REFERER

请求的来源

二、Django表单

表单提交案例:、

1、定义数据库模型

class Store(models.Model):
    s_name = models.CharField(max_length = 32) #名称
    s_address = models.TextField() #地址
    s_description = models.TextField()  # 描述
    s_picture = models.ImageField(upload_to = "img")  # 地址

imagefield需要配置upload_to来声明地址,这个地址需要和settings当中的MEDIA_ROOT结合

MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR,"static")
MEDIA_ROOT+upload_to的地址 = 文件保存的目录

2、前端构建表单

<form method="post" enctype="multipart/form-data">
    <table class="table store_table">
        <tr>
            <td rowspan="4">
                <a href="#" class="thumbnail">
                    <img src="/static/img/by.jpg">
                </a>
            </td>
            <th class="t_label">店铺名称</th>
            <td class="t_input"><input name="s_name" class="form-control" type="text" placeholder="店铺名称"></td>
            <td class="t_message",style="">店铺名称每月至多修改一次</td>
        </tr>
        <tr>
            <th class="t_label">店铺地址</th>
            <td class="t_input" colspan="2">
                <input class="form-control" name="s_address" type="text" placeholder="店铺地址">
            </td>
        </tr>
        <tr>
            <th colspan="3">店铺描述</th>
        </tr>
        <tr>
            <td colspan="3">
                <textarea class="form-control" name="s_description"></textarea>
            </td>
        </tr>
        <tr>
            <td>
                <input class="btn btn-primary" type="file" name="s_picture" value="图片上传">
            </td>
            <td colspan="3">
                <input class="btn btn-primary" type="submit" value="发起修改">
            </td>
        </tr>
    </table>
</form>

3、后端接收保存数据

注释掉 csrf 中间件:
默认django开启了csrf保护,可以通过注释settings配置来控制csrf的开关

from Goods.models import *
def store(request):
    """天天生鲜-店铺管理"""
    if request.method == "POST": #判断请求的类型
        #使用 request.POST接收数据
        s_name = request.POST.get("s_name")
        s_address = request.POST.get("s_address")
        s_description = request.POST.get("s_description")
        s_picture = request.FILES.get("s_picture")
        
        #保存数据
        s = Store()
        s.s_name = s_name
        s.s_address = s_address
        s.s_description = s_description
        s.s_picture = s_picture #图片可以直接保存
        s.save()

    return render_to_response("store.html")

三、Django CSRF

django csrf保护是通过中间件来实现的,在1.1之前django默认关闭csrf,后来默认开启

MIDDLEWARE = [
    ...
    'django.middleware.csrf.CsrfViewMiddleware',
    ...
]

在表单当中添加csrf的方法:

1、在HTML当中添加CSRF标签

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <table class="table store_table">
        <tr>
            <td rowspan="4">

2、视图需要切换render方法进行返回,render和render_to_response的区别在于render方法传递request请求到前端,这样才可以调用到csrf

def store(request):
    """天天生鲜-店铺管理"""
    if request.method == "POST": #判断请求的类型
		....
    return render(request,"store.html")

3、在实际工作当中,有的视图需要单独取消csrf保护

from Goods.models import *
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def store(request):
    """天天生鲜-店铺管理"""
    .....

四、Django后端表单校验

(一)表单类

在app当中可以定义表单类,用来渲染和进行后端数据校验

定义好的form类可以通过前端渲染成表格格式,渲染提供了三个便利的方法

方法

描述

as_p

使用p标签包含单个表单项

as_ul

使用li标签包含单个表单项

as_table

使用tr标签包含单个表单项,但是在1.8版本的django被废除

from django import forms

class StoreForm(forms.Form):
    s_name = forms.CharField(max_length = 32,label = "名称") #名称
    s_address = forms.CharField() #地址
    s_description = forms.CharField()  # 描述
    s_picture = forms.CharField()  # 地址
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {{ form }}
    <hr>
    {{ form.as_p }}
    <hr>
    {{ form.as_ul }}
    <hr>
    {{ form.as_table }}
    <hr>
    {% for i in form %}
        <div>
           {{ i.label }} {{ i }}
        </div>
    {% endfor %}
</body>
</html>

在前端调用django form表单的概率太小了,大部分是使用form进行后端校验,校验的时候必须保证前端表单的name属性和form的字段名是对应的。

(二)校验的流程

1、在表单当中定义校验规则,规则定义在字段的validator参数上,来源于django.core.validators

from django import forms
from django.core import validators #校验来与于这个方法

class StoreForm(forms.Form):
    s_name = forms.CharField(max_length = 32,label = "名称",validators = (
        validators.RegexValidator(r"\w{6,8}","用户名不合法"), #只是一个长度和类型的校验
    )) #名称,validators参数需要一共元组类型的参数,所以单元素需要加逗号
    s_address = forms.CharField() #地址
    s_description = forms.CharField()  # 描述
    s_picture = forms.CharField()  # 地址

2、校验的时候

  1. 首先绑定请求的数据到表单实例
  2. 使用is_validate方法进行校验
  3. 如果校验成功,数据使用data方法查看
  4. 如果校验失败使用errors方法查看失败提示
def storeforms(request):
    form = StoreForm()
    if request.method == "POST":
        store_data = StoreForm(request.POST)
        if store_data.is_valid():#如果校验成功,就返回True,否再False
            print(store_data.data) #校验成功后的数据,字典格式
        else:
            print(store_data.errors) #校验失败后的错误提示
    return render(request,"forms.html",locals())

(三)自定义校验

from django import forms
from django.core import validators #校验来与于这个方法
#基于面向对象,编写类,利用构造函数和__call__魔术方法编写
class OurValid:
    def __init__(self,message):
        self.message = message

    def __call__(self, value):
        if value in ["admin","dmin","min","in","n"]:
            raise validators.ValidationError(self.message)

#基于函数直接编写
def our_valid(value):
    if value in ["admin", "dmin", "min", "in", "n"]:
        raise validators.ValidationError("用户名不合适")

#在form类当中,基于clean_字段名编写
class StoreForm(forms.Form):
    s_name = forms.CharField(max_length = 32,label = "名称",validators = (
        validators.RegexValidator(r"\w{6,8}","用户名不合法"), #只是一个长度和类型的校验
        our_valid
    )) #名称,validators参数需要一共元组类型的参数,所以单元素需要加逗号
    s_address = forms.CharField() #地址
    s_description = forms.CharField()  # 描述
    s_picture = forms.CharField()  # 地址

    def clean_s_address(self):
        s_address = self.cleaned_data.get("s_address") #cleaned_data指的是校验过的数据
        if s_address in ["张家口"]:
            raise validators.ValidationError("张家口一年刮风两次,一次半年")

五、Django会话技术

Django的会话技术和Flask会话技术都是采用cookie和session技术,原理上是一致的。操作方法上十分相似。

(一)cookie操作

1. 设置

还是设置在响应上。

def views_function(request):
    response = render_to_response("index.html")
    response.set_cookie("user_id","1")
    return response

2. 获取

def views_function(request):
    user_id = request.COOKIES.get("user_id") #获取cookie
    response = render_to_response("index.html")
    response.set_cookie("user_id","1")
    return response

3. 删除

def views_function(request):
    user_id = request.COOKIES.get("user_id")
    response = render_to_response("index.html")
    response.set_cookie("user_id","1")
    response.delete_cookie("user_id") 删除cookie 
    return response

(二)session操作

session还是一个类字典对象

1. 设置

2. 获取

3. 删除

def session_function(request):
    request.session["user_id "] = 1 #设置
    user_id = request.session.get("user_id") #获取
    del request.session["user_id "] #删除