目录
day05
1.F和Q.
- F()
Author.objects.all()。update(age = F('age')+ 10)
- Q()
Q()| Q()
Author.objects.filter(Q(id = 1)| Q(age__gte = 35))
2.原生方法
- 查询 - raw()
Entry.objects.raw(sql)
使用connection.cursor()作为游标
cursor.execute(sql)增加改
3.使用后台管理模式
- 基本管理
- def __str __(个体经营)
- 内部类 - Meta
- db_table
- verbose_name
- verbose_name_plural
- 订购= []
- verbose_name
name = model.CharField(max_length =“”,verbose_name)
- 高级管理
- 管理高级类
继承自admin.ModelAdmin
注册高级管理类:admin.site.register(Entry,EntryAdmin) - 高级管理属性
- list_display
- list_display_links
- list_editable
- search_fields
- list_filter
- date_hierarchy
- 领域
- fieldsets
fieldsets =(
#分组1
('分组名称',{
'fields':('属性1','属性2'),
'classes':('collapse',),
}),
#分组2
()
)
- 管理高级类
4.关系映射
- 一对一
- 设置一对一
任何一个实体中:
属性= models.OneToOneField(Entry) - 引用反向
属性:对应的实体类名全小写
- 设置一对一
- 一对多
- 的多实体中增加对一的引用
属性= models.ForeignKey(Entry) - 引用反向
属性:类名全小写_set
- 的多实体中增加对一的引用
- 多对多
- 设置多对多
任何一个类中
属性= models.MantToManyField(Entry) - 引用反向
属性:类名全小写_set
- 设置多对多
1.Django ORM
- 自定义查询对象 - 对象
Entry.objects.filter()- 声明类EntryManager继承自modelss.Manager
允许在EntryManager中添加自定义函数
类EntryManager(models.Manager):
def函数名(self,自定义参数列表):
......
返回...... - 使用EntryManager覆盖模型类中原有的对象
类Entry(models.Model):
objects = EntryManager()
name = models.CharField (xxx)
练习:
为作者实体自定义objects对象,增加一个函数,用于查询年龄小于指定年龄值的作者的QuerySet
解析:
在index下model.py
在指数下views.py#自定义AuthorManager类,用于覆盖Author实体类中的objects class AuthorManager(models.Manager): def age_lt(self,age): return self.filter(age__lt=age) class Author(models.Model): #使用AuthorManager对象覆盖本类中的objects objects = AuthorManager() name = models.CharField(max_length=30,verbose_name='姓名') age = models.IntegerField(verbose_name='年龄') email = models.EmailField(null=True,verbose_name='邮件') #表示用户的激活状态:True,表示已激活,False,表示未激活 #由于是新增列,所以必须要给默认值或允许为空 #由于BooleanField默认是不允许为空的,所以此处选择了增加默认值 isActive = models.BooleanField(default=True,verbose_name='激活用户') #增加一个字段,表示用户的头像,可以上传的 picture = models.ImageField(upload_to="static/upload",null=True,verbose_name='头像')
def titleCount_views(request): authors = Author.objects.age_lt(45) for author in authors: print(author.name,author.age) return HttpResponse("Query OK")
- 声明类EntryManager继承自modelss.Manager
2.HttpRequest - 请求
- 什么是HttpRequest
HttpRequest,在Django中就是请求对象的封装体现,里面封装了请求过程中的所有信息,在Django中HTTPRequest被封装成了请求对象,被封装到请求处理视图函数中做为参数,在调用视图时自动传入 - 的的的HTTPRequest中的主要内容
- request.scheme:请求协议
- request.body:请求主体
- request.path:请求路径(具体资源路径)
- request.get_host():请求的主机地址/域名
- request.method:获取请求方法
- request.GET:封装了get请求方式所提交的数据
- request.POST:封装了post请求方式所提交的数据
- request.COOKIES:封装了cookies中的所有数据
- request.META:封装了请求的元数据
request.META.HTTP_REFERER:封装了请求的源地址
- 获取请求提交的数据
- get请求方式
request.GET ['名称']
request.GET.get ['名称']- 使用表单提交数据
<form method ='get'> </ form> - 通过地址拼查查询字符串
<ahref="地址?参数1=值1&参数2=值2"></A>
DJANGO中通过URL传参
URL(R '^ XXX /(\ d +)')
该写法属于Django表准并非Http标准,不能用request.GET []
- 使用表单提交数据
- post请求方式
request.POST ['名称']
CSRF:Cross-Site Request Forgery
跨站点请求伪装
解决方案:- 如果想通过CSRF验证,则需要在表单中的第一行增加
{%csrf_token%} - 取消csrf的验证
删除settings.py中MIDDLEWARE中
CsrfViewMiddleware 中间件 - 在处理函数上增加装饰器
@csrf_protect
@csrf_protect
def post_views(request):
xxx
练习:完成果园注册操作- 创建数据库 - fruit
- 创建实体类-User
uphone - 手机号
upwd - 密码
uname - 用户名
uemail - 电子邮件
isActive - 是否激活 - 完善注册模板,提交数据库时,将数据保存进数据库
解析:在指数应用models.py创建实体类
from django.db import models # Create your models here. class User(models.Model): uphone=models.CharField(max_length=11) upwd=models.CharField(max_length=20) uname=models.CharField(max_length=30) uemail=models.EmailField() isActive=models.BooleanField(default=True) def __str__(self): return self.uname class Meta: db_table = 'user'
在视图views.py保存数据
from django.http import HttpResponse from django.shortcuts import render from .models import * from .forms import * def register_views(request): # 判断是get请求还是post请求,得到用户的请求意图 if request.method == 'GET': return render(request,'register.html') else: #先验证手机号在数据库中是否存在 uphone = request.POST['uphone'] users = User.objects.filter(uphone=uphone) if users: #uphone 已经存在 errMsg = '手机号码已经存在' return render(request,'register.html',locals()) #接收数据插入到数据库中 upwd = request.POST['upwd'] uname = request.POST['uname'] uemail = request.POST['uemail'] user = User() user.uphone = uphone user.upwd = upwd user.uname = uname user.uemail = uemail user.save() return HttpResponse('注册成功')
- 如果想通过CSRF验证,则需要在表单中的第一行增加
- get请求方式
3.使用forms模块处理表单
- forms模块的作用
通过forms模块,允许将表单与class相结合,允许通过class生成表单 - 使用forms模块
- 创建forms.py文件
- 导入 django 的 forms
from django import forms - 创建class,一个class对应生成一个表单
class ClassName(forms.Form)
pass - 在class中创建属性
一个属性对应到表单中会生成一个控件forms.pyfrom django import forms # 为topic控件初始化数据 TOPIC_CHOICE = ( ('1','好评'), ('2','中评'), ('3','差评'), ) #表示评论内容的表单控件们 #控件1 - 评论标题 - 文本框 #控件2 - Email - Email框 #控件3 - 评论内容 - Textarea #控件4 - 评论级别 - Select #控件5 - 是否保存 - Checkbox class RemarkForm(forms.Form): # subject - input type='text' # label 表示的是控件前的文本 subject=forms.CharField(label='标题') # email - input type='email' email = forms.EmailField(label='邮箱') # message - Textarea # widget=forms.Textarea,表示将当前属性变为多行文本域 message = forms.CharField(label='内容',widget=forms.Textarea) # topic - Select topic = forms.ChoiceField(label='级别',choices=TOPIC_CHOICE) # isSaved - checkbox isSaved = forms.BooleanField(label='是否保存')
- 在模板中解析form对象
- 注意
- 需要自定义<form>
- 需要自定义按钮
- 处理方法
在视图中创建form的对象,并发送到模板中
ex:
form = RemarkForm()
return render(request,'xxx.html',locals())
index应用下的views.pydef form_views(request): if request.method == 'GET': form = RemarkForm() return render(request,'04-form.html',locals()) else: # subject = request.POST['subject'] # email = request.POST['email'] # message = request.POST['message'] # topic = request.POST['topic'] # isSaved = request.POST['isSaved'] # print(subject,email,message,topic,isSaved) # 通过RemarkForm自动接收数据 # 1.将request.POST数据传递给RemarkForm构造器 form = RemarkForm(request.POST) # 2.验证form对象 if form.is_valid(): # 3.通过验证后获取具体的数据 cd = form.cleaned_data subject = cd['subject'] email = cd['email'] isSaved = cd['isSaved'] message = cd['message'] topic = cd['topic'] print(subject,email,isSaved,message,topic) return HttpResponse('Post OK')
在模板中解析form对象- 手动解析
在模板中
{%for field in form%}
{{field}}表示的就是控件
{{field.label}}:表示的是控件中label的值
{%endfor%} - 自动解析
- {{form.as_p}}
将形式对象中的每个属性使用p标记包裹起来,再显示 - {{form.as_ul}}
将形成对象中的每个属性使用li标记包裹起来,再显示在网页上
注意:必须手动提供<ol> </ ol>或<ul> </ ul> - {{form.as_table}}
将形成对象中的每个属性使用TR标记包裹起来,再显示在网页上,
注意:必须手动提供的<TABLE><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> /*#id_subject{ border:2px solid #f00; }*/ input[name='subject']{ border:2px solid #ff0; border-radius:3px; } </style> </head> <body> <form action="/04-form/" method="post"> {% csrf_token %} {% comment '手动解析' %} {% for field in form %} <p> {{ field.label }}:{{ field }} </p> {% endfor %} {% endcomment %} <ul> {{ form.as_ul }} </ul> <p> <input type="submit" value="提交"> </p> </form> </body> </html>
- {{form.as_p}}
- 手动解析
- 注意
- 在视图中,通过forms.Form自动获取表单数据
- 通过forms.Form的构造器来接收post数据
form = XXXForm(request.POST) - 必须使form通过验证之后,再取值
form.is_valid()
返回True:提交的数据已通过所有验证,允许取值(返回的是一个字典)
返回False:提交的数据未通过验证,无法取值 - 电子表单杂志中数据
通过form.cleaned_data来接收提交的数据
- 通过forms.Form的构造器来接收post数据
示例请点击
udfq