写在前面
上课第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
武Sir - 笔记
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 评论个数 新闻类型 发布者 新闻图表 新闻类型表 类型名 点赞记录表 评论记录表
时间: 2024-11-09 02:45:11