标签:ima trie coder agent *** work als checkbox spec
写在前面
上课第21天,打卡:
Don‘t try so hard, the best things come when you least expect them to.
1 s17day21 2 内容回顾: 3 FBV,CBV 4 序列化 5 - Django内置 6 - json.dumps(xxx,cls=) 7 Form验证 8 - 类 9 class LoginForm(Form): 10 user = fields.CharField(...) 11 email = fields.EmailField(...) 12 email = fields.ChoiceField( 13 choices=[()..] 14 ) 15 - 添加用户: GET 16 form = LoginForm() 17 18 {{form.user}} <input type=‘text‘ name=‘user‘ /> 19 20 等待用户输入内容,提交 21 22 - 添加用户: POST 23 form = LoginForm(data=request.POST) 24 form.is_valid() 25 form.cleaned_data 26 form.errors 27 28 - 修改用户: GET /edit/9 29 obj = models.User.objects.get(id=9) 30 31 form = LoginForm(initial={‘user‘:obj.user}) 32 33 {{form.user}} <input type=‘text‘ name=‘user‘ value=‘数据库中的用户名‘ /> 34 35 等待用户输入内容,提交 36 37 - 修改用户: POST /edit/9 38 form = LoginForm(data=request.POST) 39 form.is_valid() 40 form.cleaned_data 41 models.User.objects.filter(id=9).update(**form.cleaned_data) 42 form.errors 43 44 - 补充:可以显示select,但是数据无法实时更新 45 class LoginForm(Form): 46 user = fields.CharField(...) 47 email = fields.EmailField(...) 48 hobby = fields.ChoiceField( 49 choices=[()..] 50 ) 51 52 def __init__(self,*args,**kwargs): 53 super.. 54 self.fields[‘hobby‘].choices = .... 55 56 57 今日内容概要: 58 59 - Form验证(二) 60 - 自定义验证规则 61 a. 对象 62 # phone = fields.CharField(validators=[RegexValidator(r‘^[0-9]+$‘, ‘请输入数字‘),]) 63 b. 函数 64 c. clean_字段名称 方法 65 def clean_phone(self): 66 """ 67 68 :return: 必须有返回值, 69 """ 70 # 去取用户提交的值:可能是错误的,可能是正确 71 value = self.cleaned_data[‘phone‘] 72 mobile_re = re.compile(r‘^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$‘) 73 if not mobile_re.match(value): 74 raise ValidationError(‘手机号码格式错误‘) 75 76 if models.UserInfo.objects.filter(phone=value).count(): 77 raise ValidationError(‘手机号码已经存在‘) 78 79 return value 80 **********方法中只能取当前字段的值 ********** 81 - 验证规则执行顺序 82 - 第一个字段的正则,钩子函数(方法中只能取当前字段的值) 83 - 第二个字段的正则,钩子函数 84 - 整体验证: clean,必须有返回值, 给指定字段添加错误信息 85 class RegisterForm(Form): 86 name = fields.CharField() 87 email = fields.EmailField() 88 phone = fields.CharField() 89 pwd = fields.CharField() 90 pwd_confirm = fields.CharField() 91 92 def clean(self): 93 pwd = self.cleaned_data[‘pwd‘] 94 pwd_confirm = self.cleaned_data[‘pwd_confirm‘] 95 if pwd == pwd_confirm: 96 return self.cleaned_data 97 else: 98 from django.core.exceptions import ValidationError 99 # self.add_error(‘pwd‘, ValidationError(‘密码输入不一致‘)) 100 self.add_error(‘pwd_confirm‘, ValidationError(‘密码输入不一致‘)) 101 return self.cleaned_data 102 103 - 常用插件 104 105 class RegisterForm(Form): 106 name = fields.CharField( 107 widget=widgets.TextInput(attrs={‘class‘: ‘c1‘}) 108 ) 109 email = fields.EmailField( 110 widget=widgets.EmailInput(attrs={‘class‘:‘c1‘}) 111 ) 112 phone = fields.CharField( 113 widget=widgets.Textarea(attrs={‘class‘:‘c1‘}) 114 ) 115 pwd = fields.CharField( 116 widget=widgets.PasswordInput(attrs={‘class‘:‘c1‘}) 117 ) 118 pwd_confirm = fields.CharField( 119 widget=widgets.PasswordInput(attrs={‘class‘: ‘c1‘}) 120 ) 121 # 单选:select 122 # city = fields.ChoiceField( 123 # choices=[(0,"上海"),(1,‘北京‘)], 124 # widget=widgets.Select(attrs={‘class‘: ‘c1‘}) 125 # ) 126 # 多选:select 127 # city = fields.MultipleChoiceField( 128 # choices=[(1,"上海"),(2,‘北京‘)], 129 # widget=widgets.SelectMultiple(attrs={‘class‘: ‘c1‘}) 130 # ) 131 132 # 单选:checkbox 133 # city = fields.CharField( 134 # widget=widgets.CheckboxInput() 135 # ) 136 137 # 多选:checkbox 138 # city = fields.MultipleChoiceField( 139 # choices=((1, ‘上海‘), (2, ‘北京‘),), 140 # widget=widgets.CheckboxSelectMultiple 141 # ) 142 143 # 单选:radio 144 # city = fields.CharField( 145 # initial=2, 146 # widget=widgets.RadioSelect(choices=((1,‘上海‘),(2,‘北京‘),)) 147 # ) 148 149 注意:写默认值时,多选值对应列表 150 151 # form = RegisterForm(initial={‘city‘:[1,2],‘name‘:‘alex‘}) 152 form = RegisterForm() 153 154 参考博客:http://www.cnblogs.com/wupeiqi/articles/6144178.html 155 156 - 中间件 157 - 中间件执行时机:请求到来,请求返回时 158 - 中间件是一个类: 159 def process_request(self,request): 160 print(‘m2.process_request‘) 161 162 def process_response(self,request, response): 163 print(‘m2.prcess_response‘) 164 return response 165 166 - 应用: 167 - 请求日志 168 - 用户登录认证 169 170 - 缓存 171 - 配置 172 - 开发调试 173 - 内存中 全局变量 174 - 文件中 175 - 数据库 176 - Memcached 177 - 使用 178 - 全局 179 MIDDLEWARE = [ 180 ‘django.middleware.cache.UpdateCacheMiddleware‘, 181 # 其他中间件 182 ‘django.middleware.cache.FetchFromCacheMiddleware‘, 183 ] 184 - 视图函数 185 186 from django.views.decorators.cache import cache_page 187 188 @cache_page(10) 189 def test1(request): 190 import time 191 ctime = time.time() 192 return render(request,‘test1.html‘,{‘ctime‘:ctime}) 193 - 局部模板 194 {% load cache %} 195 <!DOCTYPE html> 196 <html lang="en"> 197 <head> 198 <meta charset="UTF-8"> 199 <title>Title</title> 200 </head> 201 <body> 202 <h1>TEST1 -> {{ ctime }}</h1> 203 204 205 {% cache 10 "asdfasdfasdf" %} 206 <h1>TEST1 -> {{ ctime }}</h1> 207 {% endcache %} 208 </body> 209 </html> 210 211 - 信号 212 问题:如何在数据库中做增加操作时,记录日志 213 参考博客:http://www.cnblogs.com/wupeiqi/articles/5246483.html 214 215 - Admin 216 参考博客:http://www.cnblogs.com/wupeiqi/articles/7444717.html 217 218 - ModelForm(下周讲) 219 参考博客:http://www.cnblogs.com/wupeiqi/articles/6229414.html 220 221 - BBS项目练习: 222 地址:http://dig.chouti.com/ 223 要求: 224 表结构设计 225 功能开发: 226 页面样式和布局 227 文章列表(分页) 228 点赞:思路,发送ajax请求: 229 - 判断: 230 已经存在: like表中删除一条记录,new中like_count,自减1 231 不存在: like表中天剑一条记录,new中like_count,自加1 232 - 登录之后才能点赞 233 234 发布文章(上传图片) 235 1. 根据URL,自动获取标题和摘要 236 pip3 install beautifulsoup4 237 pip3 install requests 238 点击: 239 发送Ajax请求,将 http://music.163.com/#/song?id=188057 发送到后台 240 def get_title_summary(request): 241 url = request.POST.get(‘url‘) 242 import requests 243 from bs4 import BeautifulSoup 244 245 246 response = requests.get(‘http://music.163.com/#/song?id=188057‘) 247 soup = BeautifulSoup(response.text,‘html.parser‘) 248 title = soup.find(‘title‘).text 249 desc = soup.find(‘meta‘,attrs={‘name‘: ‘description‘}).get(‘content‘) 250 print(title) 251 print(desc) 252 data = {‘title‘:title,‘desc‘:decc} 253 return HttpResponse(json.dumps(data)) 254 2. 基于Ajax实现图片上传 255 隐藏的Input框,放置头像路径 256 257 评论 258
Django 中间件处理流程:

################
# 2017-09-17 - 课上笔记
################
day21课上笔记 .. 2017-09-17
课前回顾:
- Form组件验证
参考:http://www.cnblogs.com/wupeiqi/articles/6144178.html
- 先写好类:
class LoginForm(Form):
user = fields.CharField(...)
emial = fields.EmailField(...)
...
- 使用之添加用户
- 先实例化一个对象:form = LoginForm()
前端:{{ form.user }} -> <input type=‘text‘ name=‘user‘ />
- 等待用户输入,提交
-添加,POST
form = LoginForm(data=request.POST)
form.is_valid()
form.cleaned_data
form.errors
"""这里需要再练习下!!!"""
- 修改用户:先发一个GET请求,/edit_user/user_id
obj = models.UserInfo.objects.get(id=user_id)
form = LoginForm(initial={‘user‘:obj.user})
{{form.user}} -> <input type=‘text‘ name=‘user‘ value=‘数据库中的用户名‘ />
等待用户输入内容,提交
- 修改用户:再发一个POST请求,/edit_user/user_id
form = LoginForm(data=request.POST)
form.is_valid()
form.cleaned_data:
models.UserInfo.objects.filter(id=user_id).update(**cleaned_data)
- 下拉框无法自动刷新的问题:
‘‘‘
dp_id = fields.ChoiceField(
required=True,
choices = [],
)
def __init__(self, *args, **kwargs):
# 找到类中的所有静态字段,然后拷贝并且赋值给 self.fields
super(UserInfoForm,self).__init__(*args, **kwargs)
self.fields[‘dp_id‘].choices = models.Depart.objects.values_list(‘id‘, ‘title‘)
‘‘‘
- FBV & CBV(用到了反射)
- 序列化
- Django内置的 serializers
- json.dumps(xxx,cls=JsonCustomEncoder)
- JsonCustomEncoder 在这个函数里自定义一些规则
day21今日内容
- Form组件进行验证之进阶
‘‘‘
import re
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
‘‘‘
- 自定义验证规则方式一:使用RegexValidator对象
‘‘‘
自定义验证规则方式一:通过RegexValidator对象
phone = fields.CharField(
required=True,
validators=[RegexValidator(r‘^[0-9]+$‘, ‘请输入数字‘), RegexValidator(r‘^159[0-9]+$‘, ‘数字必须以159开头‘)],
)
‘‘‘
- 自定义验证规则方式二:自定义验证函数
‘‘‘
# 自定义验证规则函数,优点是可以有数据库操作
def phone_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(‘手机号码格式错误‘)
if models.UserInfo.objects.filter(phone=value).count():
raise ValidationError(‘手机号码已经存在‘)
phone = fields.CharField(validators=[phone_validate,])
‘‘‘
- 自定义验证规则方式三:在当前类中使用钩子函数,函数名称必须符合 "clean_字段名称"
‘‘‘
phone = fields.CharField()
# 钩子方法
def clean_phone(self,):
"""
只能取当前字段的值,切勿取其他的值
必须得有返回值
:return:
"""
# 需要要验证的值,自己写正则进行验证
# 去取用户提交的值
value = self.cleaned_data[‘phone‘]
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(‘手机号码格式错误‘)
if models.UserInfo.objects.filter(phone=value).count():
raise ValidationError(‘手机号码已经存在‘)
return value
‘‘‘
- 是否可以共存? 可以
- 顺序是怎样的?
# 看源码
1. form.is_valid()
2. self.errors
3. self.full_clean()
- self._clean_fields() # 即对 self.fields 进行循环验证,依次验证每一个字段:
先执行自己字段的正则,再执行钩子函数
先执行自己字段的正则,再执行钩子函数
...
- self._clean_form() # 字段都验证完后,再对整个form进行验证:
- self.clean()
- self.add_error(self, field, error) # 如果有错误则把错误加到add_error里
‘‘‘
class RegisterForm(Form):
name = fields.CharField(
widget=widgets.TextInput(attrs={‘class‘: ‘c1‘})
)
email = fields.EmailField(
widget=widgets.EmailInput(attrs={‘class‘:‘c1‘})
)
phone = fields.CharField(
widget=widgets.Textarea(attrs={‘class‘:‘c1‘})
)
pwd = fields.CharField(
widget=widgets.PasswordInput(attrs={‘class‘:‘c1‘})
)
pwd_confirm = fields.CharField(
widget=widgets.PasswordInput(attrs={‘class‘: ‘c1‘})
)
# 写在RegisterForm类里作用于 RegisterForm
# 以用户注册为例:用户输入密码,再次输入密码,这时候需要对两次密码进行比对
def clean(self):
pwd = self.cleaned_data[‘pwd‘]
pwd_confirm = self.cleaned_data[‘pwd_confirm‘]
if pwd == pwd_confirm:
return self.cleaned_data
else:
from django.core.exceptions import ValidationError
self.add_error(‘pwd‘, ValidationError(‘密码输入不一致‘))
self.add_error(‘pwd_confirm‘, ValidationError(‘密码输入不一致‘))
return self.cleaned_data
‘‘‘
- self._post_clean() # 等同于 self._clean_form() ,可忽略
‘‘‘
# 源代码如下:
def is_valid(self):
"""
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
@property
def errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors
def full_clean(self):
"""
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)
def _clean_form(self):
try:
cleaned_data = self.clean()
except ValidationError as e:
self.add_error(None, e)
else:
if cleaned_data is not None:
self.cleaned_data = cleaned_data
def clean(self):
"""
Hook for doing any extra form-wide cleaning after Field.clean() has been
called on every field. Any ValidationError raised by this method will
not be associated with a particular field; it will have a special-case
association with the field named ‘__all__‘.
"""
return self.cleaned_data
‘‘‘
# 添加新用户demo
‘‘‘
# models.py
class Depart(models.Model):
"""部门表"""
title = models.CharField(max_length=32) # 数据库里就是string类型
class Meta:
verbose_name_plural = "部门表"
class UserInfo(models.Model):
"""用户表"""
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
phone = models.CharField(max_length=32)
pwd = models.CharField(max_length=64)
dp = models.ForeignKey(to=‘Depart‘,to_field=‘id‘)
# forms.py
import re
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 UserInfoForm(Form):
name = fields.CharField(
required=True,
min_length=2,
max_length=12,
error_messages={‘required‘: ‘用户名不能为空‘},
widget=widgets.TextInput(attrs={‘class‘: ‘form-control‘})
) # 用户提交数据是字符串
pwd = fields.CharField(
required=True,
min_length=2,
max_length=12,
error_messages={‘required‘: ‘密码不能为空‘},
widget=widgets.PasswordInput(attrs={‘class‘: ‘form-control‘})
)
pwd_confirm = fields.CharField(
required=True,
min_length=2,
max_length=12,
error_messages={‘required‘: ‘确认密码不能为空‘},
widget=widgets.PasswordInput(attrs={‘class‘: ‘form-control‘})
)
email = fields.EmailField(
required=True,
error_messages={‘required‘: ‘邮箱不能为空‘, ‘invalid‘: ‘邮箱格式错误‘},
widget=widgets.TextInput(attrs={‘class‘: ‘form-control‘})
)
# 自定义验证规则方式三:在当前类的方法中:clean_字段名称
dp_id = fields.ChoiceField(
choices=[],
error_messages={‘required‘: ‘请选择归属部门‘},
widget=widgets.Select(attrs={‘class‘: ‘form-control‘})
)
phone = fields.CharField(error_messages={‘required‘: ‘手机号不能为空‘})
# 钩子方法
def clean_phone(self,):
"""
只能取当前字段的值,切勿取其他的值
必须得有返回值
:return:
"""
# 需要要验证的值,自己写正则进行验证
# 去取用户提交的值
value = self.cleaned_data[‘phone‘]
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(‘手机号码格式错误‘)
if models.UserInfo.objects.filter(phone=value).count():
raise ValidationError(‘手机号码已经存在‘)
return value
def __init__(self, *args, **kwargs):
# 找到类中的所有静态字段,然后拷贝并且赋值给 self.fields
super(UserInfoForm,self).__init__(*args, **kwargs)
# self.fields[‘dp_id‘].chioces = models.Depart.objects.all()
self.fields[‘dp_id‘].choices = models.Depart.objects.values_list(‘id‘, ‘title‘)
def clean(self):
print(self.cleaned_data,‘=====================‘)
pwd = self.cleaned_data.get(‘pwd‘)
pwd_confirm = self.cleaned_data.get(‘pwd_confirm‘)
if pwd == pwd_confirm:
return self.cleaned_data
else:
from django.core.exceptions import ValidationError
# self.add_error(‘pwd‘, ValidationError(‘密码输入不一致‘))
self.add_error(‘pwd_confirm‘, ValidationError(‘密码输入不一致‘))
return self.cleaned_data
# add_user.html
<form method="POST" novalidate>
{% csrf_token %}
<p> 用户名:{{ form.name }} {{ form.errors.name.0 }} </p>
<p> 密码:{{ form.pwd }} {{ form.errors.pwd.0 }} </p>
<p> 确认密码:{{ form.pwd_confirm }} {{ form.errors.pwd_confirm.0 }} </p>
<p> 邮箱:{{ form.email }} {{ form.errors.email.0 }}</p>
<p> 手机:{{ form.phone }} {{ form.errors.phone.0 }}</p>
<p> 部门:{{ form.dp_id }} {{ form.errors.dp_id.0 }}</p>
<input type="submit" value="提交" />
</form>
# views.py
def add_user(request):
if ‘GET‘ == request.method:
form = UserInfoForm()
return render(request, ‘add_user.html‘, {‘form‘: form})
else:
form = UserInfoForm(data=request.POST)
if form.is_valid():
form.cleaned_data.pop(‘pwd_confirm‘)
models.UserInfo.objects.create(**form.cleaned_data)
return redirect(‘/userinfo/‘)
return render(request, ‘add_user.html‘, {‘form‘: form})
‘‘‘
- 常用插件
参考:http://www.cnblogs.com/wupeiqi/articles/6144178.html
from django.forms import widgets
# 单选:select
# city = fields.ChoiceField(
# choices=[(0,"上海"),(1,‘北京‘)],
# widget=widgets.Select(attrs={‘class‘: ‘c1‘})
# )
# 多选:select
# city = fields.MultipleChoiceField(
# choices=[(1,"上海"),(2,‘北京‘)],
# widget=widgets.SelectMultiple(attrs={‘class‘: ‘c1‘})
# )
# 单选:checkbox
# city = fields.CharField(
# widget=widgets.CheckboxInput()
# )
# 多选:checkbox
# city = fields.MultipleChoiceField(
# choices=((1, ‘上海‘), (2, ‘北京‘),),
# widget=widgets.CheckboxSelectMultiple
# )
# 单选:radio
# city = fields.CharField(
# initial=2,
# widget=widgets.RadioSelect(choices=((1,‘上海‘),(2,‘北京‘),))
# )
- 初始化的时候赋值,包括单值和多值
注意:写默认值时,多选的值对应一个列表
- 中间件
- 中间件的执行时机:请求到来和请求返回时执行
- 中间件就是一个类,里面有2个方法(也可以没有):
process_request(self,request)
默认不写return,这本质上是 return None
process_reponse(self,request,response)
必须要写 return response
另外还有:
# 依次处理完所有request之后就进行路由匹配,然后再跳转到开头依次进行process_view函数处理
process_view(self, request, callback, callback_args, callback_kwargs)
# 捕获异常,自定义返回页面
process_exception(self,request,exception)
# Django中间件处理流程
"""
1. 循环中间件MIDDLEWARE列表里的中间件,依次执行每个中间件类的process_request(self,request)
2. 进行路由匹配,拿到对应的视图函数
3. 再次循环中间件MIDDLEWARE列表里的中间件,再从头依次执行每个中间件类的process_view(self, request, callback, callback_args, callback_kwargs)
4. 执行对应的视图函数
5. 逆序循环MIDDLEWARE列表里的中间件,依次执行每个中间件类的process_exception(self,request,exception)
6. 再次逆序循环MIDDLEWARE列表里的中间件,依次执行每个中间件类的process_template_response(...)
7. 再次逆序循环MIDDLEWARE列表里的中间件,依次执行每个中间件类的process_reponse(self,request,response)
"""
- 应用:
- 记录访问日志
- 判断用户是否登录
# 中间件要继承 MiddlewareMixin类
‘‘‘
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__()
def __call__(self, request):
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
‘‘‘
‘‘‘
HttpRequest.META
一个标准的Python 字典,包含所有的HTTP 头部。具体的头部信息取决于客户端和服务器,下面是一些示例:
CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。
CONTENT_TYPE —— 请求的正文的MIME 类型。
HTTP_ACCEPT —— 响应可接收的Content-Type。
HTTP_ACCEPT_ENCODING —— 响应可接收的编码。
HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。
HTTP_HOST —— 客服端发送的HTTP Host 头部。
HTTP_REFERER —— Referring 页面。
HTTP_USER_AGENT —— 客户端的user-agent 字符串。
QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。
REMOTE_ADDR —— 客户端的IP 地址。
REMOTE_HOST —— 客户端的主机名。
REMOTE_USER —— 服务器认证后的用户。
REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。
SERVER_NAME —— 服务器的主机名。
SERVER_PORT —— 服务器的端口(是一个字符串)。
‘‘‘
# 中间件示例1
‘‘‘
# settings.py
MIDDLEWARE = [
...
‘middle.middleware.my_middleware1‘,
‘middle.middleware.my_middleware2‘,
]
# ..\middle\middleware.py
from django.shortcuts import render,HttpResponse,redirect
from django.utils.deprecation import MiddlewareMixin
class my_middleware1(MiddlewareMixin):
def process_request(self,request):
print(‘my_middleware1.process_request...‘)
print(request.path)
print(request.path_info)
print(request.method)
print(request.META[‘REMOTE_ADDR‘])
print(request.META[‘REMOTE_HOST‘])
print(request.META[‘REQUEST_METHOD‘])
print(request.META[‘HTTP_USER_AGENT‘])
print(request.META[‘HTTP_HOST‘])
def process_response(self,request,response):
print(‘my_middleware1.process_response...‘)
return response
class my_middleware2(MiddlewareMixin):
def process_request(self,request):
print(‘my_middleware2.process_request...‘)
def process_response(self,request,response):
print(‘my_middleware2.process_response...‘)
return response
‘‘‘
# 中间件示例2 : 代替登录验证装饰器
‘‘‘
class my_middleware2(MiddlewareMixin):
def process_request(self,request):
if ‘/login/‘ == request.path_info:
return None
user_info = request.session.get(‘user_info‘)
if not user_info:
return redirect(‘/login/‘)
def process_response(self,request,response):
print(‘my_middleware2.process_response...‘)
return response
‘‘‘
- Django的缓存
参考:http://www.cnblogs.com/wupeiqi/articles/5246483.html
- 配置(默认不支持redis)
- 开发调试,相当于没有
- 本机内存中
‘‘‘
# 此缓存将内容保存至内存的变量中
# 配置:
CACHES = {
‘default‘: {
‘BACKEND‘: ‘django.core.cache.backends.locmem.LocMemCache‘,
‘LOCATION‘: ‘unique-snowflake‘,
}
}
‘‘‘
- 本地文件中
- 数据库中
- Memcached
- 使用
- 全局
MIDDLEWARE = [
‘django.middleware.cache.UpdateCacheMiddleware‘,
# 其他中间件...
‘django.middleware.cache.FetchFromCacheMiddleware‘,
]
CACHE_MIDDLEWARE_SECONDS = 10 # 设置缓存时间
- 视图函数
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def xxx(request):
pass
- 局部模板
a. 引入TemplateTag
{% load cache %}
b. 使用缓存
{% cache 5000 缓存key %}
缓存内容
{% endcache %}
- 信号
参考:http://www.cnblogs.com/wupeiqi/articles/5246483.html
Django中提供了“信号调度”,用于在框架执行操作时解耦。
通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。
需求:在对数据库做增加操作时,记录操作日志
推荐把信号的注册写到 项目目录下的 __init__()函数里
‘‘‘
# Django内置信号
Model signals
pre_init # django的modal执行其构造方法前,自动触发
post_init # django的modal执行其构造方法后,自动触发
pre_save # django的modal对象保存前,自动触发
post_save # django的modal对象保存后,自动触发
pre_delete # django的modal对象删除前,自动触发
post_delete # django的modal对象删除后,自动触发
m2m_changed # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
class_prepared # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
pre_migrate # 执行migrate命令前,自动触发
post_migrate # 执行migrate命令后,自动触发
Request/response signals
request_started # 请求到来前,自动触发
request_finished # 请求结束后,自动触发
got_request_exception # 请求异常后,自动触发
Test signals
setting_changed # 使用test测试修改配置文件时,自动触发
template_rendered # 使用test测试渲染模板时,自动触发
Database Wrappers
connection_created # 创建数据库连接时,自动触发
‘‘‘
‘‘‘
信号模块引入位置:
在项目文件加下的 __init__.py 文件里引入,并注册相关操作
信号模块引入方式:
from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception
from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate
from django.test.signals import setting_changed
from django.test.signals import template_rendered
from django.db.backends.signals import connection_created
‘‘‘
# 信号示例:旨在对数据库执行插入数据之前和之后触发各自的操作
‘‘‘
from django.db.models.signals import pre_save, post_save
def pre_save_callback(sender, **kwargs):
print(">>>>>>>>>>> pre_save")
print(sender)
print(kwargs)
def post_save_callback(sender, **kwargs):
print("################# post_save")
print(sender)
print(kwargs)
pre_save.connect(pre_save_callback)
post_save.connect(post_save_callback)
‘‘‘
# 执行结果:
‘‘‘
[18/Sep/2017 22:20:32] "POST /add_user/ HTTP/1.1" 200 1268
>>>>>>>>>>> pre_save
<class ‘app01.models.UserInfo‘>
{‘signal‘: <django.db.models.signals.ModelSignal object at 0x0000000002CE79E8>, ‘instance‘: <UserInfo: UserInfo object>, ‘using‘: ‘default‘, ‘raw‘: False, ‘update_fields‘: None}
################# post_save
<class ‘app01.models.UserInfo‘>
{‘signal‘: <django.db.models.signals.ModelSignal object at 0x0000000002CE7A90>, ‘instance‘: <UserInfo: UserInfo object>, ‘update_fields‘: None, ‘using‘: ‘default‘, ‘created‘: True, ‘raw‘: False}
[18/Sep/2017 22:20:49] "POST /add_user/ HTTP/1.1" 302 0
‘‘‘
- Admin
Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件
# 创建超级用户
‘‘‘
D:\soft\work\Python_17\day21\form_demo>python manage.py createsuperuser
Username (leave blank to use ‘liulixin‘): root
Email address:
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
Password:
Password (again):
>>>>>>>>>>> pre_save
<class ‘django.contrib.auth.models.User‘>
{‘signal‘: <django.db.models.signals.ModelSignal object at 0x0000000002CEA7F0>, ‘using‘: ‘default‘, ‘instance‘: <User: root>, ‘
raw‘: False, ‘update_fields‘: None}
################# post_save
<class ‘django.contrib.auth.models.User‘>
{‘signal‘: <django.db.models.signals.ModelSignal object at 0x0000000002CEA898>, ‘created‘: True, ‘update_fields‘: None, ‘instan
ce‘: <User: root>, ‘using‘: ‘default‘, ‘raw‘: False}
Superuser created successfully.
D:\soft\work\Python_17\day21\form_demo>
‘‘‘
更多admin做好的接口参考:http://www.cnblogs.com/wupeiqi/articles/7444717.html
Django提供的对数据库的操作,admin.py 和 models.py 配合
‘‘‘
class Depart(models.Model):
"""部门表"""
title = models.CharField(max_length=32) # 数据库里就是string类型
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "部门表"
class UserInfo(models.Model):
"""用户表"""
name = models.CharField(max_length=32)
# email = models.EmailField(max_length=32)
email = models.CharField(max_length=32)
phone = models.CharField(max_length=32)
pwd = models.CharField(max_length=64)
dp = models.ForeignKey(to=‘Depart‘,to_field=‘id‘)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "用户表"
‘‘‘
在admin.py中只需要将Mode中的某个类注册,即可在Admin中实现增删改查的功能,如:
‘‘‘
# admin.py
from django.contrib import admin
from app01 import models
# Register your models here.
admin.site.register(models.UserInfo)
admin.site.register(models.Depart)
‘‘‘
但是,这种方式比较简单,如果想要进行更多的定制操作,需要利用ModelAdmin进行操作,如:
‘‘‘
# admin.py
from django.contrib import admin
from app01 import models
# Register your models here.
class DepartAdmin(admin.ModelAdmin):
list_display = [‘id‘,‘title‘]
search_fields = [‘title‘, ]
admin.site.register(models.Depart,DepartAdmin)
class UserInfoAdmin(admin.ModelAdmin):
list_display = [‘id‘,‘name‘,‘email‘,‘phone‘,‘dp‘]
search_fields = [‘name‘, ]
admin.site.register(models.UserInfo,UserInfoAdmin)
‘‘‘
- ModelForm
- BBS项目练习
- 前端知识捡一下
- 各个小功能的设计和实现
用户表
用户名
密码
新闻表
标题
简介
点赞个数 点赞时要更新字段,Django的F实现自增1
评论个数
新闻类型
发布者
新闻图表
新闻类型表
类型名
点赞记录表
评论记录表
标签:ima trie coder agent *** work als checkbox spec
原文地址:http://www.cnblogs.com/standby/p/7545873.html