Form和modelform
参考:https://www.cnblogs.com/clschao/articles/10486468.html
Form自动生成登录标签并校验
# views.py
class LoginForm(forms.Form):
name = forms.CharField(
label='用户名:',
initial='小李',
max_length=16,
min_length=6,
widget=forms.widgets.TextInput(attrs={'class':'form-control'}), # 密码输入不可见,括号里边加样式
)
password = forms.CharField(
label='密码:',
widget=forms.widgets.PasswordInput(attrs={'class':'form-control'}), # 密码输入不可见,括号里边加样式
)
sex = forms.ChoiceField(
label='性别',
choices=((1,"男"), (2, "女"), (3, "其他")),
widget=forms.widgets.RadioSelect(),
initial=3,
)
city = forms.ChoiceField(
label='城市',
choices=((1,"北京"), (2, "上海"), (3, "东莞")),
widget=forms.widgets.Select(), # 下拉框
initial=3,
)
hobby = forms.ChoiceField(
label='爱好',
choices=((1,"抽烟"), (2, "喝酒"), (3, "烫头")),
widget=forms.widgets.CheckboxSelectMultiple, # 多选框, SelectMultiple多选下拉框
initial=3,
)
birthday = forms.CharField(
label='生日',
widget=forms.widgets.TextInput(attrs={'type':'date'}),
)
def register(request):
form_obj = LoginForm()
if request.method == 'GET':
return render(request, 'register.html',{'form_obj':form_obj})
else:
username = request.POST.get('name')
password = request.POST.get('password')
print(username, password)
return HttpResponse('登录成功')
# register.html
<form action="" method="post">
{% csrf_token %}
{# 用户名:<input type="text" name="username">#}
{# 密码:<input type="password" name="password">#}
<div>
<label for="">{{ form_obj.name.label }}</label>
{{ form_obj.name }}
</div>
<div>
<label for="">{{ form_obj.password.label }}</label>
{{ form_obj.password }}
</div>
<div>
<label>{{ form_obj.sex.label }}</label>
{{ form_obj.sex }}
</div>
<div>
<label>{{ form_obj.city.label }}</label>
{{ form_obj.city }}
</div>
<div>
<label>{{ form_obj.hobby.label }}</label>
{{ form_obj.hobby }}
</div>
<div>
<label>{{ form_obj.birthday.label }}</label>
{{ form_obj.birthday }}
</div>
{# {{ form_obj.as_p }}#}
<input type="submit">
</form>
其他属性
class LoginForm(forms.Form):
name = forms.CharField(
required=False,
label='用户名:',
initial='小李',
max_length=16,
min_length=6,
error_messages={'requried':'不能为空','min_length':'不能太短'},
widget=forms.widgets.TextInput(attrs={'class':'form-control'}), # 密码输入不可见,括号里边加样式
)
def register(request):
form_obj = LoginForm()
if request.method == 'GET':
return render(request, 'register.html',{'form_obj':form_obj})
else:
# username = request.POST.get('name')
# password = request.POST.get('password')
# print(username, password)
# request.POST = name:"ssss"
form_obj = LoginForm(request.POST)
if form_obj.is_valid(): # 做校验
print(form_obj.cleaned_data) # 通过的校验数据
else:
print(form_obj.errors)
return render(request, 'register.html', {'form_obj':form_obj})
return HttpResponse('登录成功')
{##novalidate 关闭浏览器校验#}
<form action="" method="post" novalidate>
{% csrf_token %}
{# 用户名:<input type="text" name="username">#}
{# 密码:<input type="password" name="password">#}
<div>
<label for="">{{ form_obj.name.label }}</label>
{{ form_obj.name }}
{# # 不取列表,只取一个#}
{{ form_obj.name.errors.0 }}
</div>
<input type="submit">
</form>
校验器组件
import re
from django.core.exceptions import ValidationError
def mobile_validate(value):
mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(value):
raise ValidationError('手机号码格式错误') #自定义验证规则的时候,如果不符合你的规则,需要自己发起错误
class LoginForm(forms.Form):
name = forms.CharField(
required=False,
label='用户名:',
initial='小李',
max_length=16,
min_length=6,
error_messages={'requried':'不能为空','min_length':'不能太短'},
# validators=[RegexValidator(r'^金瓶梅','没看过金瓶梅不能通过'),],
validators=[mobile_validate, ],
widget=forms.widgets.TextInput(attrs={'class':'form-control'}), # 密码输入不可见,括号里边加样式
)
Hook钩子方法
在Form类中定义钩子函数,来实现自定义的验证功能。
源码分析:https://www.bilibili.com/video/BV1aJ411H7Ej?p=405
局部钩子和全局钩子
import re
from django.core.exceptions import ValidationError
def mobile_validate(value):
mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(value):
raise ValidationError('手机号码格式错误') #自定义验证规则的时候,如果不符合你的规则,需要自己发起错误
class LoginForm(forms.Form):
name = forms.CharField(
required=False,
label='用户名:',
initial='小李',
max_length=16,
min_length=6,
error_messages={'requried':'不能为空','min_length':'不能太短'},
validators=[RegexValidator(r'^金瓶梅','没看过金瓶梅不能通过'),],
# validators=[mobile_validate, ],
widget=forms.widgets.TextInput(attrs={'class':'form-control'}), # 密码输入不可见,括号里边加样式
)
# 局部钩子
def clean_name(self):
value = self.cleaned_data['name']
if '小李' in value:
raise ValidationError('含有敏感词汇:小李')
else:
return value
# 全局钩子
def clean(self):
value = self.cleaned_data
p1 = value['password']
p2 = value['r_password']
if p1 == p2:
return value
else:
# raise ValidationError('两次输入的密码不一致')
self.add_error('r_password','两次输入的密码不一致')
raise ValidationError('两次输入的密码不一致')
<form action="" method="post" novalidate>
{% csrf_token %}
{# 用户名:<input type="text" name="username">#}
{# 密码:<input type="password" name="password">#}
<div>
<label for="">{{ form_obj.name.label }}</label>
{{ form_obj.name }}
{# # 不取列表,只取一个#}
{{ form_obj.name.errors.0 }}
</div>
<div>
<label for="">{{ form_obj.password.label }}</label>
{{ form_obj.password }}
</div>
<div>
<label for="">{{ form_obj.r_password.label }}</label>
{{ form_obj.r_password }}
</div>
# html
<body>
<div class="container">
<h1>student</h1>
<form method="POST" novalidate>
{% csrf_token %}
{# {{ student_list.as_p }}#}
{% for student in student_list %}
<div class="form-group col-md-6">
{# 拿到数据字段的verbose_name,没有就默认显示字段名 #}
<label class="col-md-3 control-label">{{ student.label }}</label>
<div class="col-md-9" style="position: relative;">{{ student }}</div>
</div>
{% endfor %}
<div class="col-md-2 col-md-offset-10">
<input type="submit" value="提交" class="btn-primary">
</div>
</form>
</div>
</body>
获取数据库中数据并展示
publishs = forms.ModelChoiceField(
label='出版社',
queryset=models.Publish.objects.all(),
)
modelform
modelform会自动生成你的model类(表)对应的字段的Form类
# models.py
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2)
publish=models.ForeignKey(to="Publish",to_field="nid")
authors=models.ManyToManyField(to='Author',)
def __str__(self):
return self.title
# views.py
class BookForm(forms.ModelForm):
class Meta:
model = models.Book
fields = "__all__"
labels = {
"title": "书名",
"price": "价格"
}
widgets = {
"password": forms.widgets.PasswordInput(attrs={"class": "c1"}),
"publishDate": forms.widgets.DateInput(attrs={"type": "date"}),
}
#局部钩子:
def clean_title(self):
pass
#全局钩子
def clean(self):
pass
def __init__(self,*args,**kwargs): #批量操作
super().__init__(*args,**kwargs)
for field in self.fields:
#field.error_messages = {'required':'不能为空'} #批量添加错误信息,这是都一样的错误,不一样的还是要单独写。
self.fields[field].widget.attrs.update({'class':'form-control'})
class meta常用参数
model = models.Book # 对应的Model中的类
fields = "__all__" # 字段,如果是__all__,就是表示列出所有的字段
exclude = None # 排除的字段
labels = None # 提示信息
help_texts = None # 帮助提示信息
widgets = None # 自定义插件
error_messages = None # 自定义错误信息
error_messages = {
'title':{'required':'不能为空',...} #每个字段的所有的错误都可以写,...是省略的意思,复制黏贴我代码的时候别忘了删了...
}
任务
CRM 客户关系管理系统
(jq22.com 登录注册模板 扒页面模板)
同源和跨域
https://www.cnblogs.com/clschao/articles/10745966.html
深入理解python异步编程
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
简单请求跨域
创建两个django项目,第一个叫做s1,一个叫做s2,s1用8000端口启动,s2用8001端口启动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>s1的首页</h2>
<button id="btn">Ajax请求</button>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.js"></script>
<script>
$('#btn').click(function () {
$.ajax({
//url:'/books/', 访问自己服务器的路由,同源(ip地址、协议、端口都相同才是同源)
url:'http://127.0.0.1:8001/books/', //访问其他服务器的路由,不同源,那么你可以访问到另外一个服务器,但是浏览器将响应内容给拦截了,并给你不同源的错误:Access to XMLHttpRequest at 'http://127.0.0.1:8001/books/' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://127.0.0.1:8002' that is not equal to the supplied origin.
#并且注意ip地址和端口后面是一个斜杠,如果s2的这个url没有^books的^符号,那么可以写两个//。 type:'get',
success:function (response) {
console.log(response);
}
})
})
</script>
</body>
</html>
from django.shortcuts import render,HttpResponse
from django.http import JsonResponse
# Create your views here.
def index(request):
return render(request,'index.html')
def books(request):
# return JsonResponse(['西游记','三国演义','水浒传'],safe=False)
obj = JsonResponse(['西游记','三国演义','水浒传'],safe=False)
return obj
# s2
from django.shortcuts import render
from django.http import JsonResponse
# Create your views here.
def books(request):
# return JsonResponse(['西游记2','三国演义2','水浒传2'],safe=False)
obj = JsonResponse(['西游记2','三国演义2','水浒传2'],safe=False)
#下面这个响应头信息是告诉浏览器,不要拦着,我就给它,"*"的意思是谁来请求我,我都给
# obj["Access-Control-Allow-Origin"] = "*"
obj["Access-Control-Allow-Origin"] = "http://127.0.0.1:8000" #只有这个ip和端口来的请求,我才给他数据,其他你浏览器帮我拦着
return obj