目录
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) - 增删改
with connection.cursor() as cursor
cursor.execute(sql)
3.使用后台管理Models
- 基本管理
- def __str__(self)
- 内部类 - Meta
- db_table
- verbose_name
- verbose_name_plural
- ordering = []
- 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
- fields
- fieldsets
fieldsets =(
#分组1
('分组名称',{
'fields':('属性1','属性2'),
'classes':('collapse',),
}),
#分组2
()
)
- 管理高级类
4.关系映射
- 一对一
- 设置一对一
任何一个实体中:
属性= models.OneToOneField(Entry) - 反向引用
属性:对应的实体类名全小写
- 设置一对一
- 一对多
- 的多实体中增加对一的引用
属性= models.ForeignKey(Entry) - 反向引用
属性:类名全小写_set
- 的多实体中增加对一的引用
- 多对多
- 设置多对多
任何一个类中
属性= models.MantToManyField(Entry) - 反向引用
属性:类名全小写_set
- 设置多对多
1.Django ORM
- 自定义查询对象 - objects
Entry.objects.filter()- 声明类EntryManager继承自modelss.Manager
允许在EntryManager中添加自定义函数
class EntryManager(models.Manager):
def 函数名(self,自定义参数列表):
... ...
return ... ... - 使用 EntryManager 覆盖Models类中原有的objects
class Entry(models.Model):
objects = EntryManager()
name = models.CharField(xxx)
练习:
为Author 实体自定义 objects对象,增加一个函数,用于查询年龄小于指定年龄值的作者的QuerySet
解析:
在index下 model.py
在index下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:封装了后请求方式所提交的数据
- request.COOKIES : 封装了 cookies 中的所有数据
- request.META:封装了请求的元数据
request.META.HTTP_REFERER:封装了请求的源地址
- 获取请求提交的数据
- get请求方式
request.GET ['名称']
request.GET.get ['名称']- 使用表单提交数据
<form method='get'></form> - 通过地址拼查查询字符串
<a href="地址?参数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 dhango 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}}
将form对象中的每个属性使用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.is_valid()
返回True:提交的数据已通过所有验证,允许取值(返回的是一个字典)
返回False:提交的数据未通过验证,无法取值 - 表单电子杂志中数据
通过form.cleaned_data来接收提交的数据
- 通过forms.Form的构造器来接收post数据
示例请点击
udfq