Python【day 18】:django学习--models\admin
modelform
1、forms
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'Administrator' from django import forms #不能直接import forms 不然就把自己导入进去了 from app01 import models #3Modelform 简洁 class bookmodelform(forms.ModelForm): class Meta:#这个modelform不用写form验证了,默认models中已经有验证了 model = models.book #book是表名(也是models中的类名) 定义绑定哪个表 # fields = '__all__' #显示数据库所有字段 exclude=() #显示数据库所有字段 可以设置不显示的字段 # fields = ("title","publication_date") #默认显示所有的字段,这里可以设置只显示其中几个字段 #是fields,而不是field,拼写 一个字段 必须加上逗号 widgets = { #给title字段自定义属性-样式 "title" : forms.TextInput(attrs={"class":"form-control"}), #样式前台没有生效?已解决 15行和10行对齐 #widgets需要和model对齐,而不是和class Meta对齐 拼写 }
2、views
#3modelform def book_modelform(request): form = forms.bookmodelform() #文件名.类名 新建一个实例对象 初始化不带数据 if request.method =="POST": #如果是提交 print(request.POST) #输出用户的输入或者选择 form = forms.bookmodelform(request.POST) #将提交的数据作为参数传入 带数据 if form.is_valid(): #如果表格验证通过 print("form is ok") # print(form.cleaned_data) #获取所有提交的数据 form.save() #保存 modelform对比form 这个操作就将前台输入的保存到了数据库 return render(request,"app01/book_modelform.html",{"book_modelform":form}) #拼写 book_modelform.html 少了 html 看报错提示
3、models
class book(models.Model): title = models.CharField(max_length=64) authors = models.ManyToManyField(author) #多对多--通过中间表进行关联 publishers =models.ForeignKey(publisher) #一对多(一个出版社可以出版多本书,每本书只有一个出版商 # 每本书需要单选出版商# ) #外键是一个对象,这个对象代表的是另外一个表的一行数据 #可以通过外键.字段的形式获取另外一个表的字段 publication_date =models.DateField() def __str__(self): #py3是str return "[%s]" % self.title def __unicode__(self): return "[%s]" % self.title
4、HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> {# .form-control{#} {# background-color: green;#} {# }#} .form-ele{ padding: 10px; {# 内边距#} } </style> </head> <body> <form action="" method="post">{% csrf_token %} {# {{ book_modelform }}#} {# <select name="publishers_id">#} {# 必须是publishers_id 如果少了s会报错#} {# {% for i in publishers %}#} {# <option value="{{ i.id }}">{{ i.name }}</option>#} {# {% endfor %}#} {# </select>#} <div class=""> {% for i in book_modelform %} <div class="form-ele">{{ i.name }}:{{ i }}{{ i.errors }}</div> {# {{ i.name }}:{{ i }}{{ i.errors }} 显示字段名、输入框、验证错误提示默认的#} {% endfor %} <input type="submit" value="创建图书"/> </div> </form> </body> </html>
二、admin定制
Django Admin django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查,而使用django admin 则需要以下步骤: 创建后台管理员 配置url 注册和配置django admin后台管理页面 1、创建后台管理员 1 python manage.py createsuperuser 2、配置后台管理url 1 url(r'^admin/', include(admin.site.urls)) 3、注册和配置django admin 后台管理页面 a、在admin中执行如下配置 from django.contrib import admin from app01 import models admin.site.register(models.UserType) admin.site.register(models.UserInfo) admin.site.register(models.UserGroup) admin.site.register(models.Asset) b、设置数据表名称 class UserType(models.Model): name = models.CharField(max_length=50) class Meta: verbose_name = '用户类型' verbose_name_plural = '用户类型' c、自定义页面展示 class UserInfoAdmin(admin.ModelAdmin): list_display = ('username', 'password', 'email') admin.site.register(models.UserType) admin.site.register(models.UserInfo,UserInfoAdmin) admin.site.register(models.UserGroup) d、添加页面搜索过滤等功能 from django.contrib import admin from app01 import models class UserInfoAdmin(admin.ModelAdmin): list_display = ('username', 'password', 'email') search_fields = ('username', 'email') list_filter = ('username', 'email') admin.site.register(models.UserType) admin.site.register(models.UserInfo,UserInfoAdmin) admin.site.register(models.UserGroup) admin.site.register(models.Asset)
admin.py
from django.contrib import admin from app01 import models # Register your models here. class bookAdmin(admin.ModelAdmin): #自定义页面展示 # 1、自定义展示 list_display = ("id",'title', 'publishers',"publication_date") #注意 一对多的字段authors不能在admin显示,否则报错 # list_display = ('title', 'publishers',"publication_date","authors") #2、搜索 search_fields = ("title","publishers__name") #根据书名title搜素 根据出版社名字,搜索该出版社出版的书 双下杠是跨表-外键 #3、过滤 list_filter = ("publishers__name","publication_date") #1个参数必须加上逗号,否则报错,外键__字段 跨表查询 #4、批量修改 list_editable = ("title","publication_date") #注意要修改title,必须在8行--list_display显示id 默认第一列无法修改 #5、分页 list_per_page = 10 #每页显示10条 #单页内的定制 #6、多对对,选作者,如果作者名单是100多个,拖滚动条就不行了 filter_horizontal = ("authors",) #多对多字段 (定制多选框) #for m2m #7、一对多,选出版社,定制下拉框 raw_id_fields = ("publishers",) #for FK admin.site.register(models.author) admin.site.register(models.book,bookAdmin) #自定义页面的类展示在admin页面 admin.site.register(models.publisher)
3、admin action
实现批量修改和加颜色
models.py
class book(models.Model): title = models.CharField(max_length=64) authors = models.ManyToManyField(author) #多对多--通过中间表进行关联 publishers =models.ForeignKey(publisher) #一对多(一个出版社可以出版多本书,每本书只有一个出版商 # 每本书需要单选出版商# ) #外键是一个对象,这个对象代表的是另外一个表的一行数据 #可以通过外键.字段的形式获取另外一个表的字段 publication_date =models.DateField() status_choices =( #元组嵌套元组 #添加一个下拉框 ("published","已出版"), #元组 ("producing","待出版"), ("forbidden","禁书"), ) status = models.CharField(choices=status_choices,max_length=32,default="producing") #添加字段,需要加上默认值 def __str__(self): #py3是str return "[%s]" % self.title def __unicode__(self): return "[%s]" % self.title # from django.utils.html import format_html #导入format_html def colored_status(self): #在admin.py中的20行 自定义展示 list_play 加上这个函数名 if self.status == "published": #给状态添加颜色 format_td = format_html('<span style="padding:2px;background-color:green;color:white">已出版</span>') elif self.status == "producing": format_td = format_html('<span style="padding:2px;background-color:pink;color:white">待出版</span>') elif self.status == "forbidden": format_td = format_html('<span style="padding:2px;background-color:red;color:white">禁书</span>') return format_td colored_status.short_description = "状态" #给colored_status重命名成"状态" 在admin前台页面显示 # title.short_description = "标题" 自定义字段可以修改重命名 数据库本身字段无法重命名 #background 少了字母n 拼写 前台显示不出来
admin.py
#!/usr/bin/env python #-*- coding:utf-8 -*- from django.contrib import admin from app01 import models #需求1:实现admin字段的定制 #需求2:实现批量修改, #需求3:实现批量修改的字段带有底色,字体颜色 # Register your models here. def make_forbidden(ModelAdmin,request,queryset): #38行 print("--->",request,queryset) #<WSGIRequest: POST '/admin/app01/book/'> [<book: [11]>] queryset.update(status="forbidden") #将勾选的书批量修改成forbidden make_forbidden.short_description = "set to forbidden" #action的下拉选项的名字 # make_forbidden后面没有小括号() 拼写 class bookAdmin(admin.ModelAdmin): #自定义页面展示 # 1、自定义展示 colored_status是models中的函数名字 实现不同的状态不同的底色和字体颜色 list_display = ("id",'title', 'publishers',"publication_date","colored_status") #注意 一对多的字段authors不能在admin显示,否则报错 # list_display = ("id",'title', 'publishers',"publication_date","status","colored_status") #注意 一对多的字段authors不能在admin显示,否则报错 # list_display = ('title', 'publishers',"publication_date","authors") #2、搜索 search_fields = ("title","publishers__name") #根据书名title搜素 根据出版社名字,搜索该出版社出版的书 双下杠是跨表-外键 #3、过滤 list_filter = ("publishers__name","publication_date") #1个参数必须加上逗号,否则报错,外键__字段 跨表查询 #4、首页字段修改(类似全选反选取消) list_editable = ("title","publication_date") #注意要修改title,必须在8行--list_display显示id 默认第一列无法修改 #5、分页 list_per_page = 10 #每页显示10条 #单页内的定制 #6、多对对,选作者,如果作者名单是100多个,拖滚动条就不行了 filter_horizontal = ("authors",) #多对多字段 (定制多选框) #for m2m #7、一对多,选出版社,定制下拉框 raw_id_fields = ("publishers",) #for FK 必须逗号 #8、首页批量修改(例如批量将选中的书 状态变成forbidden) 7行 actions =[make_forbidden,] #必须逗号 actions而不是action 拼写 admin.site.register(models.author) admin.site.register(models.book,bookAdmin) #自定义页面的类展示在admin页面 admin.site.register(models.publisher)
4、在自己写的脚本中调用models
1、models
#!/usr/bin/env python #-*- coding:utf-8 -*- from __future__ import unicode_literals from django.db import models # Create your models here. #分类、微博、作者表 from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def __str__(self): # __unicode__ on Python 2 return self.name class Author(models.Model): name = models.CharField(max_length=50) email = models.EmailField() def __str__(self): # __unicode__ on Python 2 return self.name class Entry(models.Model): blog = models.ForeignKey(Blog) #外键 博客和分类 一对多 外键 headline = models.CharField(max_length=255) body_text = models.TextField() pub_date = models.DateField() mod_date = models.DateField() authors = models.ManyToManyField(Author) #博客的和作者 多对多 n_comments = models.IntegerField() n_pingbacks = models.IntegerField() rating = models.IntegerField() def __str__(self): # __unicode__ on Python 2 return self.headline
2、admin
from django.contrib import admin # Register your models here. from blog import models admin.site.register(models.Blog) admin.site.register(models.Author) admin.site.register(models.Entry)
3、自定义脚本文件
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'Administrator' import os,sys #需求1:将entry文章(硅谷钢铁侠)的分类从科技,修改成生活 (外键,一对多关联) 19-23行 #需求2:将entry文章(硅谷钢铁侠)的作者添加多个(多对多关联) 29-32行 add os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day16_django1.settings") #从 manage.py拷贝过来 import django django.setup() #要想通过单独写脚本orm_test.py来调用models,就必须先配置环境变量 7-9行 单独运行这个文件,不报错,就代表配置好了 #单独写脚本可以代替python manage.py shell的命令行执行 from blog import models #从app-blog导入models from blog.models import Author entry = models.Entry.objects.get(pk=1) #取entry表中的主键是1的那条博客记录--硅谷钢铁侠 life_blog = models.Blog.objects.get(name="生活") #取分类表中name=生活的那条记录的名称--生活 entry.blog = life_blog #这里blog是外键,代表另外一个表-分类表的名字--生活 entry.save() #保存后生效 print(entry.blog) #这里blog是外键,代表另外一个表-分类表的名字--生活 print(entry) #硅谷钢铁侠 输出entry博客的名称 print(life_blog) #生活 输出分类表的科技这条记录 from blog.models import Author #从app-blog中导入作者表 joe = Author.objects.create(name="Joe") #给作者表增加一条记录name="Joe" 先创建表后添加 print(joe) #Joe john = Author.objects.create(name="John") paul = Author.objects.create(name="paul") entry.authors.add(john, paul) #一次添加多个作者 # entry.authors.add(joe) #将作者添加到博客表的多对多字段authors 可以多选(下拉框) 一次添加一个作者
五、对同一表内不同的字段进行对比查询 F语法
1、admin
from django.contrib import admin # Register your models here. from blog import models class entryadmin(admin.ModelAdmin): list_display = ("blog","headline","pub_date","mod_date","n_comments","n_pingbacks") admin.site.register(models.Blog) admin.site.register(models.Author) admin.site.register(models.Entry,entryadmin)
2、自定义脚本py文件
#对同一表内不同的字段进行对比查询 F语法 from django.db.models import F obj = models.Entry.objects.filter(n_comments__lt=F('n_pingbacks')) #小于 # obj = models.Entry.objects.filter(n_comments__lte=F('n_pingbacks')) #小于等于 # select n_comments,n_pingbacks from Entry where n_comments < n_pingbacks 原生sql # n_comments小于n_pingbacks print(obj) #[<Entry: 硅谷钢铁侠>]
六、and和or and是逗号表示 or是Q表示 Q语法
1、自定义py文件
#and和or and是逗号表示 or是Q表示 Q语法 from django.db.models import F,Q obj1 = models.Entry.objects.filter(n_comments__lt=F('n_pingbacks'),pub_date__gte="2016-05-01") print(obj1) #[<Entry: 硅谷钢铁侠>] 这里逗号表示and并且的意思 obj2 = models.Entry.objects.filter(Q(n_comments__lt=F('n_pingbacks'))|Q(pub_date__gt="2016-05-01")) print(obj2) #[<Entry: 硅谷钢铁侠>] 两个Q一个竖杠 是或or的意思