构建一个表单

这是一个非常简单的表单。实际应用中,一个表单可能包含几十上百个字段,其中大部分需要预填充,而且我们预料到用户将来回编辑-提交几次才能完成操作。

我们可能需要在表单提交之前,在浏览器端作一些验证。我们可能想使用非常复杂的字段,以允许用户做类似从日历中挑选日期这样的事情,等等。

这个时候,让Django 来为我们完成大部分工作是很容易的。

在Django 中构建一个表单

Form 类

我们已经计划好了我们的 HTML 表单应该呈现的样子。在Django 中,我们的起始点是这里:

form模块
from django.forms import Form #继承Form类
from django.forms import fields #验证字段
from django.forms import widgets #通过widgets来更改form表单中的样式
xxxxxxxxxx
5
 
1
form模块
2
from django.forms import Form                 #继承Form类
3
from django.forms import fields               #验证字段
4
from django.forms import widgets              #通过widgets来更改form表单中的样式
5

from django.forms import Form                 #继承Form类
from django.forms import fields #验证字段
from django.forms import widgets #通过widgets来更改form表单中的样式
class TeacherForm(Form)
username = fields.CharField(
required=True, #True字段不能为空,false字段可以为空
error_messages={'required':'用户名不能为空'}, #报错信息可以指定添加报错信息,不指定的话就是默认的报错信息
widget=widgets.TextInput(attrs={'placeholder':'用户名','class':'form-control'}) #可以给表单添加样式然后在前端页面渲染出来
) # 不能为空
password = fields.CharField(required=True,
error_messages={'required':'密码不能为空'},
widget=widgets.TextInput(attrs={'placeholder':'密码','class':'form-control'})) # 不能为空
email = fields.EmailField(required=True,
error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'}, # 不能为空,且邮箱格式
widget=widgets.EmailInput(attrs={'placeholder':'邮箱','class':'form-control'}))
xxxxxxxxxx
19
 
1
from django.forms import Form                 #继承Form类
2
from django.forms import fields               #验证字段
3
from django.forms import widgets              #通过widgets来更改form表单中的样式
4
class TeacherForm(Form)
5
    username = fields.CharField(
6
        required=True,                         #True字段不能为空,false字段可以为空
7
        error_messages={'required':'用户名不能为空'},     #报错信息可以指定添加报错信息,不指定的话就是默认的报错信息
8
        widget=widgets.TextInput(attrs={'placeholder':'用户名','class':'form-control'}) #可以给表单添加样式然后在前端页面渲染出来
9
    ) # 不能为空
10
    password = fields.CharField(required=True,
11
                                error_messages={'required':'密码不能为空'},
12
                                widget=widgets.TextInput(attrs={'placeholder':'密码','class':'form-control'})) # 不能为空
13
    email = fields.EmailField(required=True,
14
                              error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'},              # 不能为空,且邮箱格式
15
                              widget=widgets.EmailInput(attrs={'placeholder':'邮箱','class':'form-control'}))   
16
    
17
    
18

19

视图

发送给Django 网站的表单数据通过一个视图处理,一般和发布这个表单的是同一个视图。这允许我们重用一些相同的逻辑。

当处理表单时,我们需要在视图中实例化它:

def add_teacher(request):
if request.method == 'GET':
form = TeacherForm()
return render(request,'add_teacher.html',{'form':form})
else:
"""
1. 用户请求数据验证
2. 自动生成错误信息
3. 打包用户提交正确信息
4. 错误:保留上次输入内容
5. 定制页面上显示的HTML标签
Django Form组件
1. 创建规则(类,字段)
class Foo:
username = xxx
password = xxx
email = xxx
2. 数据和规则进行匹配
"""
form = TeacherForm(data=request.POST) # 数据和规则放置一起
if form.is_valid(): # 开始校验,并获取校验结果
# print('执行成功',form.cleaned_data) # 所有匹配成功,字典
# {'username': 'asd', 'password': 'sdf', 'email': 'sadf@live.com','ut_id':1}
form.cleaned_data['ut_id'] = 1
models.UserInfo.objects.create(**form.cleaned_data)
return redirect('/teachers/') return render(request, 'add_teacher.html',{'form':form})
xxxxxxxxxx
28
 
1
def add_teacher(request):
2
    if request.method == 'GET':
3
        form = TeacherForm()
4
        return render(request,'add_teacher.html',{'form':form})
5
    else:
6
        """
7
        1. 用户请求数据验证
8
        2. 自动生成错误信息
9
        3. 打包用户提交正确信息
10
        4. 错误:保留上次输入内容
11
        5. 定制页面上显示的HTML标签
12
        Django Form组件
13
        1. 创建规则(类,字段)
14
            class Foo:
15
                username = xxx
16
                password = xxx
17
                email = xxx
18
        2. 数据和规则进行匹配
19
        """
20
        form = TeacherForm(data=request.POST) # 数据和规则放置一起
21
        if form.is_valid():                       # 开始校验,并获取校验结果
22
            # print('执行成功',form.cleaned_data)          # 所有匹配成功,字典
23
            # {'username': 'asd', 'password': 'sdf', 'email': 'sadf@live.com','ut_id':1}
24
            form.cleaned_data['ut_id'] = 1
25
            models.UserInfo.objects.create(**form.cleaned_data)
26
            return redirect('/teachers/')
27

28
        return render(request, 'add_teacher.html',{'form':form})

如果访问视图的是一个GET 请求,它将创建一个空的表单实例并将它放置到要渲染的模板的上下文中。这是我们在第一个访问该URL 时预期发生的情况。

如果表单的提交使用POST 请求,那么视图将再次创建一个表单实例并使用请求中的数据填充它:form = NameForm(request.POST)。这叫做”绑定数据至表单“(它现在是一个绑定的表单)。

我们调用表单的is_valid()方法;如果它不为True,我们将带着这个表单返回到模板。这时表单不再为空(未绑定),所以HTML 表单将用之前提交的数据填充,然后可以根据要求编辑并改正它。

如果is_valid()True,我们将能够在cleaned_data 属性中找到所有合法的表单数据。在发送HTTP 重定向给浏览器告诉它下一步的去向之前,我们可以用这个数据来更新数据库或者做其它处理。

模板

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>添加老师</h1>
<form method="POST" novalidate>
{% csrf_token %}
<p>{{ form.username }} {{ form.errors.username.0 }} </p> #直接通过后端上下文对应调用名字,通过form.errors.username.0来调用错误信息
<p>{{ form.email }} {{ form.errors.email.0 }} </p>
<p>{{ form.password }} {{ form.errors.password.0 }} </p> <input type="submit" value="提交" /> </form>
</body>
</html>
xxxxxxxxxx
22
 
1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
    <meta charset="UTF-8">
5
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
    <meta name="viewport" content="width=device-width, initial-scale=1">
7
    <title>Title</title>
8
</head>
9
<body>
10
    <h1>添加老师</h1>
11
<form method="POST" novalidate>
12
    {% csrf_token %}
13
    <p>{{ form.username }} {{ form.errors.username.0 }} </p>    #直接通过后端上下文对应调用名字,通过form.errors.username.0来调用错误信息
14
    <p>{{ form.email }} {{ form.errors.email.0 }} </p>
15
    <p>{{ form.password }} {{ form.errors.password.0 }} </p>
16

17
    <input type="submit" value="提交" />
18

19

20
</form>
21
</body>
22
</html>

根据{{ form }},所有的表单字段和它们的属性将通过Django 的模板语言拆分成HTML 标记 。

注:Django 原生支持一个简单易用的跨站请求伪造的防护。当提交一个启用CSRF 防护的POST 表单时,你必须使用上面例子中的csrf_token 模板标签。

现在我们有了一个可以工作的网页表单,它通过Django Form 描述、通过视图处理并渲染成一个HTML <form>

Django Form 类详解

form字段参数

	 #密码验证
- max_length
- min_length
- validators = [RegexValidator('xxx')] #正则表达式 通过正则表达式来进行验证
xxxxxxxxxx
5
 
1
     #密码验证
2
     - max_length
3
     - min_length
4
     - validators = [RegexValidator('xxx')]      #正则表达式 通过正则表达式来进行验证
5

示例:
        password = fields.CharField(
required=True,
min_length=3,
max_length=18,
error_messages={
'required': '密码不能为空',
'min_length': '密码长度不能小于3',
'max_length': '密码长度不能大于18',
'invalid': '密码格式错误', #如果加上xxx的话invalid也要改xxx要相同的名字
},
validators=[RegexValidator('\d+','只能是数字','xxxx') ] #****注意当两个相同的判断都生效时,上面的优先级更高
)
xxxxxxxxxx
12
 
1
        password = fields.CharField(
2
        required=True,
3
        min_length=3,
4
        max_length=18,
5
        error_messages={
6
            'required': '密码不能为空',
7
            'min_length': '密码长度不能小于3',
8
            'max_length': '密码长度不能大于18',
9
            'invalid': '密码格式错误',           #如果加上xxx的话invalid也要改xxx要相同的名字
10
        },
11
        validators=[RegexValidator('\d+','只能是数字','xxxx') ]     #****注意当两个相同的判断都生效时,上面的优先级更高
12
    )

验证登陆
from django.shortcuts import render,redirect,HttpResponse
from django.conf import settings
# Create your views here.
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from app01 import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
class LoginForm(Form):
username = fields.CharField(
required=True,
min_length=3,
max_length=18,
error_messages={
'required': '用户不能为空',
'min_length': '用户长度不能小于3',
'max_length': '用户长度不能大于18',
}
)
password = fields.CharField(
required=True,
min_length=3,
max_length=18,
error_messages={
'required': '密码不能为空',
'min_length': '密码长度不能小于3',
'max_length': '密码长度不能大于18',
'invalid': '密码格式错误', #如果加上xxx的话invalid也要改xxx要相同的名字
},
validators=[RegexValidator('\d+','只能是数字') ] #****注意当两个相同的判断都生效时,上面的优先级更高
)
''' 之前的方法
# def clean_username(self):
# # ...
# user = self.cleaned_data['username']
# is_exsit = models.UserInfo.objects.filter(username=user).count()
# if not is_exsit:
# raise ValidationError('用户名不存在')
# return user
#
# def clean_password(self):
# user = self.cleaned_data['username']
# return user
'''
def login(request): #现在用form进行验证
if request.method == "GET":
form = LoginForm()
return render(request, 'login.html', {'form': form})
elif request.method == "POST":
form = LoginForm(data=request.POST)
# <tr><th><label for="id_password">Password:</label></th><td><input type="text" name="password" value="123" maxlength="18" minlength="3" requir 这里form拿到的是前端页面上的所有input框中的代码
ed id="id_password" /></td></tr> if form.is_valid(): #先进行form验证
# 验证成功
user = models.UserInfo.objects.filter(**form.cleaned_data).first() #这里接收的话需要加上**form表单验证成功在进行数据库验证
if not user:
# 如果验证错误用户名或密码错误
# form.add_error('password','用户名或密码错误')
form.add_error('password', ValidationError('用户名或密码错误')) #则主动抛出错误
return render(request, 'login.html', {'form': form})
else:
request.session[settings.SJF] = {'id': user.id, 'username': user.username}
return redirect('/index/')
else:
# 验证失败
return render(request, 'login.html', {'form': form})
else:
return HttpResponse('滚')
xxxxxxxxxx
71
 
1
from django.shortcuts import render,redirect,HttpResponse
2
from django.conf import settings
3
# Create your views here.
4
from django.forms import Form
5
from django.forms import fields
6
from django.forms import widgets
7
from app01 import models
8
from django.core.validators import RegexValidator
9
from django.core.exceptions import ValidationError
10
class LoginForm(Form):
11
    username = fields.CharField(
12
        required=True,
13
        min_length=3,
14
        max_length=18,
15
        error_messages={
16
            'required': '用户不能为空',
17
            'min_length': '用户长度不能小于3',
18
            'max_length': '用户长度不能大于18',
19
        }
20
    )
21
    password = fields.CharField(
22
        required=True,
23
        min_length=3,
24
        max_length=18,
25
        error_messages={
26
            'required': '密码不能为空',
27
            'min_length': '密码长度不能小于3',
28
            'max_length': '密码长度不能大于18',
29
            'invalid': '密码格式错误',                    #如果加上xxx的话invalid也要改xxx要相同的名字
30
        },
31
        validators=[RegexValidator('\d+','只能是数字') ]       #****注意当两个相同的判断都生效时,上面的优先级更高
32
    )
33
'''  之前的方法
34
    # def clean_username(self):
35
    #     # ...
36
    #     user = self.cleaned_data['username']
37
    #     is_exsit = models.UserInfo.objects.filter(username=user).count()
38
    #     if not is_exsit:
39
    #         raise ValidationError('用户名不存在')
40
    #     return user
41
    #
42
    # def clean_password(self):
43
    #     user = self.cleaned_data['username']
44
    #     return user
45
'''
46
def login(request):            #现在用form进行验证
47
    if request.method == "GET":
48
        form = LoginForm()
49
        return render(request, 'login.html', {'form': form})
50
    elif request.method == "POST":
51
        form = LoginForm(data=request.POST)
52
       # <tr><th><label for="id_password">Password:</label></th><td><input type="text" name="password" value="123" maxlength="18" minlength="3" requir     这里form拿到的是前端页面上的所有input框中的代码
53
ed id="id_password" /></td></tr>
54

55
        if form.is_valid():           #先进行form验证
56
            # 验证成功
57
            user = models.UserInfo.objects.filter(**form.cleaned_data).first()   #这里接收的话需要加上**form表单验证成功在进行数据库验证
58
            if not user:
59
                # 如果验证错误用户名或密码错误
60
                # form.add_error('password','用户名或密码错误')
61
                form.add_error('password', ValidationError('用户名或密码错误'))   #则主动抛出错误
62
                return render(request, 'login.html', {'form': form})
63
            else:
64
                request.session[settings.SJF] = {'id': user.id, 'username': user.username}
65
                return redirect('/index/')
66
        else:
67
            # 验证失败
68
            return render(request, 'login.html', {'form': form})
69
    else:
70
        return HttpResponse('滚')
71







Django Form 扩展

钩子函数

form运行的过程
当用户进行验证时,会有两个值username,password,拿到两个值后,会进行一个循环验证是否有这两个,

    @property                                        #2        #当视图函数调用时,@property不需要()就可以调用
def errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean() #3 #通过full_clean()拿到全部的值之后调用
return self._errors def is_valid(self): #1 #可以看到iv_valid验证,
"""
Returns True if the form has no errors. Otherwise, False. If errors are
being ignored, returns False.
"""
return self.is_bound and not self.errors def full_clean(self): #4
"""
Cleans all of self.data and populates self._errors and
self.cleaned_data.
"""
self._errors = ErrorDict()
if not self.is_bound: # Stop further processing.
return
self.cleaned_data = {}
# If the form is permitted to be empty, and none of the form data has
# changed from the initial data, short circuit any validation.
if self.empty_permitted and not self.has_changed():
return self._clean_fields()
self._clean_form()
self._post_clean() def _clean_fields(self): #执行里面的方法
for name, field in self.fields.items(): #进行一个循环,把用户传过来的值进行循环验证
# value_from_datadict() gets the data from the data dictionaries.
# Each widget type knows how to retrieve its own data, because some
# widgets split data over several HTML fields.
if field.disabled:
value = self.get_initial_for_field(field, name)
else:
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
try:
if isinstance(field, FileField):
initial = self.get_initial_for_field(field, name)
value = field.clean(value, initial)
else:
value = field.clean(value)
self.cleaned_data[name] = value
if hasattr(self, 'clean_%s' % name):
value = getattr(self, 'clean_%s' % name)()
self.cleaned_data[name] = value
except ValidationError as e:
self.add_error(name, e)
xxxxxxxxxx
61
 
1
当用户进行验证时,会有两个值username,password,拿到两个值后,会进行一个循环验证是否有这两个,
2

3

4

5

6
    @property                                        #2        #当视图函数调用时,@property不需要()就可以调用
7
    def errors(self):
8
        "Returns an ErrorDict for the data provided for the form"
9
        if self._errors is None:
10
            self.full_clean()                      #3        #通过full_clean()拿到全部的值之后调用
11
        return self._errors
12

13
    def is_valid(self):                             #1      #可以看到iv_valid验证,
14
        """
15
        Returns True if the form has no errors. Otherwise, False. If errors are
16
        being ignored, returns False.
17
        """
18
        return self.is_bound and not self.errors
19

20

21

22
    def full_clean(self):                          #4          
23
        """
24
        Cleans all of self.data and populates self._errors and
25
        self.cleaned_data.
26
        """
27
        self._errors = ErrorDict()
28
        if not self.is_bound:  # Stop further processing.
29
            return
30
        self.cleaned_data = {}
31
        # If the form is permitted to be empty, and none of the form data has
32
        # changed from the initial data, short circuit any validation.
33
        if self.empty_permitted and not self.has_changed():
34
            return
35

36
        self._clean_fields()
37
        self._clean_form()
38
        self._post_clean()
39

40
    def _clean_fields(self):                          #执行里面的方法
41
        for name, field in self.fields.items():           #进行一个循环,把用户传过来的值进行循环验证
42
            # value_from_datadict() gets the data from the data dictionaries.
43
            # Each widget type knows how to retrieve its own data, because some
44
            # widgets split data over several HTML fields.
45
            if field.disabled:
46
                value = self.get_initial_for_field(field, name)
47
            else:
48
                value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
49
            try:
50
                if isinstance(field, FileField):
51
                    initial = self.get_initial_for_field(field, name)
52
                    value = field.clean(value, initial)
53
                else:
54
                    value = field.clean(value)
55
                self.cleaned_data[name] = value
56
                if hasattr(self, 'clean_%s' % name):
57
                    value = getattr(self, 'clean_%s' % name)()
58
                    self.cleaned_data[name] = value
59
            except ValidationError as e:
60
                self.add_error(name, e)
61

from django.shortcuts import render,redirect,HttpResponse
from django.conf import settings
# Create your views here.
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from app01 import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
class LoginForm(Form):
username = fields.CharField( #每一个进来的值,先进行正则,在进行钩子函数
required=True,
min_length=3,
max_length=18,
error_messages={
'required': '用户不能为空',
'min_length': '用户长度不能小于3',
'max_length': '用户长度不能大于18',
}
)
password = fields.CharField( #在进来一个值,先进行正则,在执行钩子函数
required=True,
min_length=3,
max_length=18,
error_messages={
'required': '密码不能为空',
'min_length': '密码长度不能小于3',
'max_length': '密码长度不能大于18',
'invalid': '密码格式错误',
},
validators=[RegexValidator('\d+','只能是数字') ]
) #自定义函数
def clean_username(self):
# ...
user = self.cleaned_data['username'] #这样拿到用户的值
is_exsit = models.UserInfo.objects.filter(username=user).count() #通过models进行用户的验证
if not is_exsit: #如果没有值
raise ValidationError('用户名不存在') #则抛出错误,用户名不存在
return user #在返回回去,如果没返回的话会一直拿到的是空值 def clean_password(self): #注意,这里只能拿自己的字段不能拿别人的字段,用户拿过来的值是字典,字典是无序的,不知道是先执行的username,还是password,
user = self.cleaned_data['username']
return user def login(request):
if request.method == "GET":
form = LoginForm()
return render(request, 'login.html', {'form': form})
elif request.method == "POST":
form = LoginForm(data=request.POST)
print(form)
if form.is_valid():
# 验证成功
user = models.UserInfo.objects.filter(**form.cleaned_data).first()
if not user:
# 用户名或密码错误
# form.add_error('password','用户名或密码错误')
# form.add_error('username',ValidationError('用户名错误'))
form.add_error('password', ValidationError('用户名密码错误'))
return render(request, 'login.html', {'form': form})
else:
request.session[settings.SJF] = {'id': user.id, 'username': user.username}
return redirect('/index/')
else:
# 验证失败
return render(request, 'login.html', {'form': form})
else:
return HttpResponse('滚')
xxxxxxxxxx
71
 
1
from django.shortcuts import render,redirect,HttpResponse
2
from django.conf import settings
3
# Create your views here.
4
from django.forms import Form
5
from django.forms import fields
6
from django.forms import widgets
7
from app01 import models
8
from django.core.validators import RegexValidator
9
from django.core.exceptions import ValidationError
10
class LoginForm(Form):
11
    username = fields.CharField(                   #每一个进来的值,先进行正则,在进行钩子函数
12
        required=True,
13
        min_length=3,
14
        max_length=18,
15
        error_messages={
16
            'required': '用户不能为空',
17
            'min_length': '用户长度不能小于3',
18
            'max_length': '用户长度不能大于18',
19
        }
20
    )
21
    password = fields.CharField(                #在进来一个值,先进行正则,在执行钩子函数
22
        required=True,
23
        min_length=3,
24
        max_length=18,
25
        error_messages={
26
            'required': '密码不能为空',
27
            'min_length': '密码长度不能小于3',
28
            'max_length': '密码长度不能大于18',
29
            'invalid': '密码格式错误',
30
        },
31
        validators=[RegexValidator('\d+','只能是数字') ]
32
    )
33
    
34
     #自定义函数
35
    def clean_username(self):
36
        # ...
37
        user = self.cleaned_data['username']                 #这样拿到用户的值
38
        is_exsit = models.UserInfo.objects.filter(username=user).count()     #通过models进行用户的验证
39
        if not is_exsit:                                          #如果没有值
40
            raise ValidationError('用户名不存在')                  #则抛出错误,用户名不存在
41
        return user                                             #在返回回去,如果没返回的话会一直拿到的是空值
42

43
    def clean_password(self):                        #注意,这里只能拿自己的字段不能拿别人的字段,用户拿过来的值是字典,字典是无序的,不知道是先执行的username,还是password,
44
        user = self.cleaned_data['username']
45
        return user
46

47
def login(request):
48
    if request.method == "GET":
49
        form = LoginForm()
50
        return render(request, 'login.html', {'form': form})
51
    elif request.method == "POST":
52
        form = LoginForm(data=request.POST)
53
        print(form)
54
        if form.is_valid():
55
            # 验证成功
56
            user = models.UserInfo.objects.filter(**form.cleaned_data).first()
57
            if not user:
58
                # 用户名或密码错误
59
                # form.add_error('password','用户名或密码错误')
60
                # form.add_error('username',ValidationError('用户名错误'))
61
                form.add_error('password', ValidationError('用户名密码错误'))
62
                return render(request, 'login.html', {'form': form})
63
            else:
64
                request.session[settings.SJF] = {'id': user.id, 'username': user.username}
65
                return redirect('/index/')
66
        else:
67
            # 验证失败
68
            return render(request, 'login.html', {'form': form})
69
    else:
70
        return HttpResponse('滚')
71



中间件

中间件是什么
中间件是一个类



当我们登陆验证需要使用装饰器来装饰session来进行登陆验证是否带着session来没有则返回login页面,这样的话太麻烦了,在视图中少数的函数还好,当成百上千的函数出现时还需要这种方式吗
装饰器函数登陆验证示例:
def auth(func):
def inner(request,*args,**kwargs):
user_info = request.session.get(settings.SJF)
if not user_info:
return redirect('/login/')
return func(request,*args,**kwargs)
return inner
@auth #当进入index页面验证是否带有session
def index(request):
username = request.session[settings.SJF]['username']
return render(request,'index.html',{'username':username}) @auth
def teachers(request):
# models.UserInfo.objects.filter(ut__title='讲师')
teacher_list = models.UserInfo.objects.filter(ut_id=1) return render(request,'teachers.html',{'teacher_list':teacher_list})
xxxxxxxxxx
19
 
1
def auth(func):
2
    def inner(request,*args,**kwargs):
3
        user_info = request.session.get(settings.SJF)
4
        if not user_info:
5
            return redirect('/login/')
6
        return func(request,*args,**kwargs)
7
    return inner
8
@auth                                                 #当进入index页面验证是否带有session
9
def index(request):
10
    username = request.session[settings.SJF]['username']
11
    return render(request,'index.html',{'username':username})
12

13
@auth
14
def teachers(request):
15
    # models.UserInfo.objects.filter(ut__title='讲师')
16
    teacher_list = models.UserInfo.objects.filter(ut_id=1)
17

18
    return render(request,'teachers.html',{'teacher_list':teacher_list})
19

那怎么解决呢,这就需要中间件了,先来一张中间件的流程图

加入我们有一个中间件,中间件里面有函数m1 m2 m3 当浏览器从request,m1 m2 m3 进去,当返回时,会从response,m3 m2 m1出来 
当浏览器访问时,进入login页面登陆会先经过中间件这样我们可以在中间件加入判断,如果运行成功中间件默认无返回值是None之后继续执行后续的中间件和视图函数,如果有返回值则直接从自己的prcess_request进去则从自己的prcess_response返回给浏览器,
示例:
from django.conf import settings
from django.shortcuts import redirect
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__() def __call__(self, request): #call方法让子类继承
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response class M1(MiddlewareMixin): #里面继承类 def process_request(self,request):
# 无返回值:继续执行后续中间件和视图函数
# 有返回值:执行自己的process_response和上面的response
# request.xxxx= 888
# request.path_info # /login/
if request.path_info == "/login/": #取路径,需要login页面一直是放开的,所以不对login做验证
return None user_info = request.session.get(settings.SJF) #取session,有session值的话是true,
if not user_info: #没有session的话则直接返回login
return redirect('/login/')
def process_response(self,request,response):
print('m1.process_response')
return response
class M2(MiddlewareMixin): def process_request(self,request):
print('m2.process_request')
def process_response(self,request,response):
print('m2.process_response')
return response
xxxxxxxxxx
41
 
1
from django.conf import settings
2
from django.shortcuts import redirect
3
class MiddlewareMixin(object):
4
    def __init__(self, get_response=None):
5
        self.get_response = get_response
6
        super(MiddlewareMixin, self).__init__()
7

8
    def __call__(self, request):             #call方法让子类继承
9
        response = None
10
        if hasattr(self, 'process_request'):
11
            response = self.process_request(request)
12
        if not response:
13
            response = self.get_response(request)
14
        if hasattr(self, 'process_response'):
15
            response = self.process_response(request, response)
16
        return response
17

18

19
class M1(MiddlewareMixin):      #里面继承类
20

21
    def process_request(self,request):
22
        # 无返回值:继续执行后续中间件和视图函数
23
        # 有返回值:执行自己的process_response和上面的response
24
        # request.xxxx= 888
25
        # request.path_info # /login/
26
        if request.path_info == "/login/":            #取路径,需要login页面一直是放开的,所以不对login做验证
27
            return None
28

29
        user_info = request.session.get(settings.SJF)         #取session,有session值的话是true,
30
        if not user_info:                                      #没有session的话则直接返回login
31
            return redirect('/login/')
32
    def process_response(self,request,response):
33
        print('m1.process_response')
34
        return response
35
class M2(MiddlewareMixin):
36

37
    def process_request(self,request):
38
        print('m2.process_request')
39
    def process_response(self,request,response):
40
        print('m2.process_response')
41
        return response
中间件的使用路径
 

django中间件做过什么

            - 用户登录
- 日志记录
- csrf
- session
- 权限管理***
xxxxxxxxxx
5
 
1
            - 用户登录 
2
            - 日志记录
3
            - csrf
4
            - session
5
            - 权限管理***



数据源无法实时更新

		1. headmaster_id
2. 数据源无法实施更新,重写构造方法
方式一(推荐):
class ClassForm(Form):
caption = fields.CharField(error_messages={'required':'班级名称不能为空'})
# headmaster = fields.ChoiceField(choices=[(1,'娜娜',)])
headmaster_id = fields.ChoiceField(choices=[]) def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.fields['headmaster_id'].choices =models.UserInfo.objects.filter(ut_id=2).values_list('id','username') 方式二: from django.forms.models import ModelChoiceField
class ClassForm(Form):
caption = fields.CharField(error_messages={'required':'班级名称不能为空'})
# headmaster = fields.ChoiceField(choices=[(1,'娜娜',)])
headmaster_id = ModelChoiceField(queryset=models.UserInfo.objects.filter(ut_id=2))
x
 
1
        1. headmaster_id
2
        2. 数据源无法实施更新,重写构造方法
3
       方式一(推荐):
4
                class ClassForm(Form):
5
                    caption = fields.CharField(error_messages={'required':'班级名称不能为空'})
6
                    # headmaster = fields.ChoiceField(choices=[(1,'娜娜',)])
7
                    headmaster_id = fields.ChoiceField(choices=[])
8

9
                    def __init__(self,*args,**kwargs):
10
                        super().__init__(*args,**kwargs)
11
                        self.fields['headmaster_id'].choices =models.UserInfo.objects.filter(ut_id=2).values_list('id','username')
12

13
            方式二:
14
            
15
                from django.forms.models import ModelChoiceField
16
                class ClassForm(Form):
17
                    caption = fields.CharField(error_messages={'required':'班级名称不能为空'})
18
                    # headmaster = fields.ChoiceField(choices=[(1,'娜娜',)])
19
                    headmaster_id = ModelChoiceField(queryset=models.UserInfo.objects.filter(ut_id=2))






















django-from的更多相关文章

  1. 异步任务队列Celery在Django中的使用

    前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...

  2. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  3. django server之间通过remote user 相互调用

    首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...

  4. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  5. Mysql事务探索及其在Django中的实践(一)

    前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...

  6. 《Django By Example》第三章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第三章滚烫出炉,大家请不要吐槽文中 ...

  7. 《Django By Example》第二章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:翻译完第一章后,发现翻译第二章的速 ...

  8. 《Django By Example》第一章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:本人目前在杭州某家互联网公司工作, ...

  9. Django

    一.Django 简介 Django 是一个由 Python 写成的开放源代码的 Web 应用框架.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统) ...

  10. Django admin定制化,User字段扩展[原创]

    前言 参考上篇博文,我们利用了OneToOneField的方式使用了django自带的user,http://www.cnblogs.com/caseast/p/5909248.html , 但这么用 ...

随机推荐

  1. POJ 1252 Euro Efficiency(完全背包, 找零问题, 二次DP)

    Description On January 1st 2002, The Netherlands, and several other European countries abandoned the ...

  2. ref 属性使用eslint报错

    react 使用 ref 报错 ,[eslint] Using string literals in ref attributes is deprecated. (react/no-string-re ...

  3. MQTT--单片机实现即时通信

    链接--->http://blog.csdn.net/zhou6343178/article/details/51182623 1.准备条件: a)硬件:ATMEGA644PA 8位单片机 EN ...

  4. 关于微信的jsdk的若干亲身实践之小结

    前言: 业务来源:自主研发的手机app软件有分享文章到微信或者QQ以及微博的功能,而在微信中再次点击分享按钮的时候,情况就出现的不可把控了: 文章显示的缩略图不能正常显示:文章的简介不能显示……而我们 ...

  5. cocos2d-x游戏引擎核心之九——跨平台

    一.cocos2d-x跨平台 cocos2d-x到底是怎样实现跨平台的呢?这里以Win32和Android为例. 1. 跨平台项目目录结构 先看一下一个项目创建后的目录结构吧!这还是以HelloCpp ...

  6. mySQL数据库二:命令行的使用

    在做整理的时候,上一篇刚开始只是简单的做了个数据类型的开头,在这里简单说一下mySQL的使用以及它的命令行 1.准备工作 有一个好的开发工具可以几何倍数的增加我们的工作效率,所以,工具是必不可少的,首 ...

  7. poj_3258 二分法

    题目大意 给定区间[0,L],在区间内给定N个数,加上区间的端点总共N+2个值.这N+2个数相邻的两个数之间有一个差值delta[i],现在可以从除去端点之外的这N个数中删除M个,使得剩余的N+2-M ...

  8. postgres模板数据库

    CREATE DATABASE 实际上是通过拷贝一个现有的数据库进行工作的.缺省时,它拷贝名为 template1 的标准系统数据库.所以该数据库是创建新数据库的"模板".如果你给 ...

  9. web基础----->模板引擎Velocity的使用(二)

    这里面是关于velocity的一些用法,比较基础的使用.愿你生命中有够多的云翳,来造成一个美丽的黄昏. velocity生成javaBean 一.定义一个简单的bean类 public class C ...

  10. Deploying Cloud Foundry on OpenStack Juno and XenServer (Part I)

    link http://rabbitstack.github.io/deploying-cloud-foundry-on-openstack-juno-and-xenserver-part-i/ Cl ...