哪些请求方式在请求地址的时候可以带请求体?
只有PATCH、POST、PUT、DELETE访问一个url地址时可以带请求体
作用:
1.路由分发(根据url找到对应的处理函数)
2.调用处理函数进行业务处理。
web服务器 app.run()
作用:
1.解析请求报文,调用框架程序处理请求。
2.组织响应报文,返回内容给客户端。
如何搭建工程程序
工程的组建
工程的配置
路由定义
视图函数的定义
如何获取请求数据(操作request对象)
如何构造响应数据(构造response对象)
如何使用中间层
请求钩子
框架提供的其他功能组件
数据库
模板
admin
Django的主要目的是简便、快速的开发数据库驱动的网站。强调代码复用、快速开发和DRY(不要自己重复造轮子)原则。
Django原生提供了众多的功能组件,让开发更简便快速。
Model(模型)-View(视图)-Template(模板)
Model,负责和数据库交互,进行数据处理
View,用于接收请求,处理业务逻辑
Template,负责封装构造要返回的html
其实和MVC框架一样
mkvirtualenv name -p python3 # 创建虚拟环境
workon name # 进入虚拟环境
pip install django==1.11.11 # 安装django
cd 目录 # 切换目录
django-admin startproject <项目名称> # 创建项目
python manage.py startapp #创建子应用
点开项目目录下的settings,在INSTALLED_APPS中配置
python manage.py runserver
定义在子应用的views.py中
需要request接收请求并返回响应对象
def index(requset):
"""request:接收请求对象"""
# 返回相应对象
return HttpResponse('hello world')
from django.conf.urls import url
from users import views
urlpatterns = [
# 添加当前子应用中url地址和视图函数之间的对应关系
# url('地址url正则表达式','对应视图函数')
url(r'index',views.index),
]
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 包含子应用中urls.py文件
url(r'^users/',include('users.urls'))
]
先找项目总的urls.py中正则匹配url地址,调用视图函数,再进入子应用中的urls.py进行正则匹配,调用视图函数
在子应用中进行url配置时,严格匹配开头和结尾
Django url 地址配置的默认风格时:末尾加/
url(r'^index/$', views.index)
总的应用中定义别名用namespace=’’
url(r'^users/', include('users.urls', namespace='users')),
子应用中定义别名用name=’’
url(r'^index/$', views.index, name='index'),
根据视图获取对应的url地址,通常配合重定向进行使用。
def url_reverse(request):
# 获取index视图所对应的url地址
from django.urls import reverse
req_url = reverse('users:index')
return HttpResponse('OK')
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
在settings.py中配置
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
# LANGUAGE_CODE = 'en-us' # 设置语言
LANGUAGE_CODE = 'zh-Hans' # 设置语言
# TIME_ZONE = 'UTC' # 设置时区
TIME_ZONE = 'Asia/Shanghai' # 设置时区
在settings.py中配置
1)设置访问静态文件路径的前缀地址
2)指定Django中静态文件存放的目录
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
# 设置访问静态文件路径的前缀地址
STATIC_URL = '/static/'
# 指定Django中静态文件存放的目录
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
#/weather/城市名/年份/:比如:/weather/shanghai/2019/
#flask: 路由转换器 /weather//
#Django:
#未命名参数按定义顺序传递,正则需要小括号括起来,分组
#在urls中配置正则
url(r'^weather/([a-z]+)/(\d{4})/$', views.weather),
#在视图函数中获取
def weather(request, city, year):
print('city=%s' % city)
print('year=%s' % year)
return HttpResponse('OK')
#命名参数按名字传递
#在urls中配置正则 ?P给参数起别名
url(r'^weather/(?P[a-z]+)/(?P\d{4})/$' , views.weather),
#在视图函数中获取
def weather(request, year, city):
print('city=%s' % city)
print('year=%s' % year)
return HttpResponse('OK')
# /qs/?a=1&b=2&c=3&c=4
# flask:request.args
def get_qs(request):
# 获取查询字符串的参数
a = request.GET.get('a')
b = request.GET.get('b')
c = request.GET.get('c') # ,如果c对应多个值,默认只查询到最后一个值
clist = request.GET.getlist('c') # 使用此方法可以查询c的列表
return HttpResponse('OK')
表单数据:/from_data/
request.POST:QueryDict类型的对象,允许一个键对应多个值
request.POST.get('name')
request.POST.get('age')
<from methods='get' action='提交地址'>
<input type='text' name='a'/>
<input type='text' name='b'/>
<input type='submit' value='提交'/>
</from>
json数据:/json_data/
request.body
import json
def get_body_json(request):
json_str = request.body
json_str = json_str.decode() # python3.6 无需执行此步
req_data = json.loads(json_str)
print(req_data['a'])
print(req_data['b'])
return HttpResponse('OK')
注意:使用postman必须注释csrf功能,另外postman测试的时候网址后面一定要加斜杠!!!
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
/header_data/
request.META:python 字典,保存请求头中的所有数据
请求中的任何HTTP头部转换为HTTP_的键时,都会将所有字母大写并将连接符替换为下划线,最后加上META前缀
request.META.get('HTTP_NAME')
# /header_data/
def get_header(request):
# 获取请求头传递的参数
type = request.META.get('CONTENT_TYPE')
name = request.META.get('HTTP_NAME')
return HttpResponse('OK')
视图访问响应时返回HttpResponse类的对象或者子类的对象
response = HttpResponse(content='响应内容', content_type='响应体数据类型', status='状态码')
response['NAME'] = 'ITCAST' #响应头可以直接将HttpResponse对象当做字典进行响应头键值对的设置
return response
# 示例
# /get_response/
def get_response(request):
# 响应对象构造
response = HttpResponse('content body', content_type='text/html', status=200)
# 向响应头中添加数据
response['NAME'] = 'ITCAST'
return response
# 反向解析获取index视图所对应的url地址
req_url = reverse('users:index')
return redirect(req_url)
from django.http import JsonResponse
return JsonResponse({'name':monkey,'age',23})
diango中cookie的设置和获取:
response = HttpResponse('ok')
response.set_cookie(cookie名, value=cookie值, max_age=cookie有效期) # 3600(一小时过期)
return response
读取:
def demo_view(request):
name = request.COOKIES.get('name')
print(name)
return HttpResponse('OK')
删除:
def del_cookie(request):
response = HttpResponse('OK')
response.delete_cookie('name')
return response
session:数据存储在服务器,以key-value进行存储。
特点: session依赖于cookie,每个客户端的session数据的标识存储到cookie中
flask session过期时间默认一个月,django session过期时间默认为2周。
1.数据库
存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式。
SESSION_ENGINE='django.contrib.sessions.backends.db'
2.混合本地缓存
存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。
SESSION_ENGINE='django.contrib.sessions.backends.cache'
3.混合存储
优先从本机内存中存取,如果没有则从数据库中存取。
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
安装扩展 pip install django-redis
在settings.py文件中做如下设置 (缓存可以有多个空间,需要多个空间复制default从新命名就行了)
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
# /set_session/
def set_session(request):
# 设置session
request.session['name'] = 'itcast'
request.session['age'] = 12
return HttpResponse('OK')
# /get_session/
def get_session(request):
# 获取session
name = request.session.get('name')
age = request.session.get('age')
return HttpResponse('name: %s age: %s' % (name, age))
1) 以键值对的格式写session。
request.session['键']=值
2)根据键读取值。
request.session.get('键',默认值)
3)清除所有session,在存储中删除值部分。
request.session.clear()
4)清除session数据,在存储中删除session的整条数据。
request.session.flush()
5)删除session中的指定键及值,在存储中只删除某个键及对应的值。
del request.session['键']
6)设置session的有效期
request.session.set_expiry(value)
类视图好处:
1.代码更加清晰 2.代码可重用性更高
class RegisterView(View):
def get(self,request):
# 返回注册页面
return HttpResponse('返回注册页面')
def post(self,request):
# 进行注册处理
return HttpResponse('进行注册处理')
def put(self,request):
# 使用哪个方法请求就def定义哪个请求方式
return HttpResponse('put方法被调用')
# 子应用配置urls.py
urlpatterns = [
url(r'^register/$', views.RegisterView.as_view(), name='register')
]
# 项目总的urls设置包含
注意:函数视图的装饰器不能直接加在类视图方法上面,会报错!
1)方法一:在urls中配置中装饰
2)方法二:使用@method_decorator来进行装饰器添加
def my_decorator(func):
def wrapper(request, *args, **kwargs):
print('自定义装饰器被调用了')
print('请求路径%s' % request.path)
return func(request, *args, **kwargs)
return wrapper
# 为全部请求方法添加装饰器
@method_decorator(my_decorator, name='dispatch')
class DemoView(View):
def get(self, request):
print('get方法')
return HttpResponse('ok')
def post(self, request):
print('post方法')
return HttpResponse('ok')
# 为特定请求方法添加装饰器
@method_decorator(my_decorator, name='get')
class DemoView(View):
def get(self, request):
print('get方法')
return HttpResponse('ok')
def post(self, request):
print('post方法')
return HttpResponse('ok')
把一些通用的功能封装到不同的父类中,子类需要哪些功能,就可以继承哪些父类,这些父类就是Mixin扩展类。
DRF框架
Django中的中间件,就类似于flask中的钩子函数:可以让我们在请求之前或之后做一些处理。
1)在子应用目录下创建middleware.py(但是作用域时全局的),将以下模板代码复制到里面
def simple_middleware(get_response):
# 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。
def middleware(request):
# 此处编写的代码会在每个请求处理视图前被调用。
response = get_response(request)
# 此处编写的代码会在每个请求处理视图之后被调用。
return response
return middleware
2)在settings.py中注册
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'users.middleware.my_middleware', # 添加中间件
]
init部分的代码调用和中间件的注册顺序是相反的
before request部分的代码和中间件的注册顺序是相同的
after request部分的代码和中间件的注册顺序是相反的
可以在请求之前设置CSRF跨站请求伪造判断保护
可以在请求之前设置黑名单校验
1.创建并设置模板文件的目录
2.在视图中使用render(request,‘模板文件’,‘字典’)调用模板
class TemplateView(View):
def get(self,request):
return render(request,'temp.html',context={'content':'hello'})
3.在urls中注册地址
1.加载模板文件:指定所使用的模板文件,获取模板对象
from django.template inport loader
temp = loader.get_template('模板文件')
2.进行模板渲染:给模板文件传递数据,将模板文件中的变量进行替换,获取替换之后的内容
res_html = temp.render('传递给模板文件的字典数据')
3.创建响应对象
return HttpResponse(res_html)
Django使用模板变量时,无论是字典、列表或元组的元素,都需要使用".",不能使用[]
Django中的模板变量不能直接进行算术运算
def index(request):
context = {
'city': '北京',
'adict': {
'name': '西游记',
'author': '吴承恩'
},
'alist': [1, 2, 3, 4, 5]
}
return render(request, 'index.html', context)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ city }}</h1>
<h1>{{ adict }}</h1>
<h1>{{ adict.name }}</h1> 注意字典的取值方法
<h1>{{ alist }}</h1>
<h1>{{ alist.0 }}</h1> 注意列表的取值方法
</body>
</html>
Django模板中在进行条件判断时,比较操作符的两边必须有空格
for循环:
{% for item in 列表 %}
循环逻辑
{{forloop.counter}}表示当前是第几次循环,从1开始
{%empty%} 列表为空或不存在时执行此逻辑
{% endfor %}
if条件:
{% if ... %}
逻辑1
{% elif ... %}
逻辑2
{% else %}
逻辑3
{% endif %}
比较运算符如下:
==
!=
<
>
<=
>=
布尔运算符如下:
and
or
not
注意:运算符左右两侧不能紧挨变量或常量,必须有空格。
{% if a == 1 %} # 正确
{% if a==1 %} # 错误
{{模板变量|过滤器:参数}}
注:Django中的过滤器冒号后面的参数只能有一个
safe,禁用转义,告诉模板这个变量是安全的,可以解释执行
length,长度,返回字符串包含字符的个数,或列表、元组、字典的元素个数。
default,默认值,如果变量不存在时则返回默认值。
data|default:'默认值'
date,日期,用于对日期类型的值进行字符串格式化,常用的格式化字符如下:
Y表示年,格式为4位,y表示两位的年。
m表示月,格式为01,02,12等。
d表示日, 格式为01,02等。
j表示日,格式为1,2等。
H表示时,24进制,h表示12进制的时。
i表示分,为0-59。
s表示秒,为0-59。
value|date:"Y年m月j日 H时i分s秒"
1)单行注释语法如下:
{#...#}
2)多行注释使用comment标签,语法如下:
{% comment %}
...
{% endcomment %}
定义代码块:
{% block 名称 %}
预留区域,可以编写默认内容,也可以没有默认内容
{% endblock 名称 %}
子模版继承:
{% extends "父模板路径"%}
{% block 名称 %}
实际填充内容
{{ block.super }}用于获取父模板中block的内容
{% endblock 名称 %}
Django自带ORM框架:通过类和对象可以直接进行数据库操作,根据模型类自动生成表
使用MySQL数据库首先需要安装驱动程序
pip install PyMySQL
在Django的工程同名子目录的__init__.py文件中添加如下语句
from pymysql import install_as_MySQLdb
install_as_MySQLdb()
作用是让Django的ORM能以mysqldb的方式来调用PyMySQL。
修改DATABASES配置信息
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '127.0.0.1', # 数据库主机
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': 'mysql', # 数据库用户密码
'NAME': 'django_demo' # 数据库名字
}
}
在MySQL中创建数据库
create database django_demo default charset=utf8;
定义模型类,在models.py文件中定义
class BookInfo(models.Model):
"""图书类模型"""
# 字段属性 = models.字段类型(选项参数)
btitle = models.CharField(max_length=20,verbose_name="标题")
class Meta:
# 指定表名
db_table = "tb_books"
1) 数据库表名
模型类如果未指明表名,Django默认以 小写app应用名_小写模型类名 为数据库表名。
可通过db_table 指明数据库表名。
2) 关于主键
django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后django不会再创建自动增长的主键列。
默认创建的主键列属性为id,可以使用pk代替,pk全拼为primary key。
3) 属性命名限制
不能是python的保留关键字。
不允许使用连续的下划线,这是由django的查询方式决定的。
定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性=models.字段类型(选项)
4)字段类型
类型 | 说明 |
---|---|
AutoField | 自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性 |
BooleanField | 布尔字段,值为True或False |
NullBooleanField | 支持Null、True、False三种值 |
CharField | 字符串,参数max_length表示最大字符个数 |
TextField | 大文本字段,一般超过4000个字符时使用 |
IntegerField | 整数 |
DecimalField | 十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数 |
FloatField | 浮点数 |
DateField | 日期, 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误 |
TimeField | 时间,参数同DateField |
DateTimeField | 日期时间,参数同DateField |
FileField | 上传文件字段 |
ImageField | 继承于FileField,对上传的内容进行校验,确保是有效的图片 |
5) 选项
选项 | 说明 |
---|---|
null | 如果为True,表示允许为空,默认值是False |
db_column | 字段的名称,如果未指定,则使用属性的名称 |
db_index | 若值为True, 则在表中会为此字段创建索引,默认值是False |
default | 默认 |
primary_key | 若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用 |
unique | 如果为True, 这个字段在表中必须有唯一值,默认值是False |
6) 外键
在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:
生成迁移文件
python manage.py makemigrations
同步到数据库中
python manage.py migrate
Django shell 终端环境使用:
python manage.py shell
mysql数据库的日志文件:
记录mysql数据库操作
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
# 1.创建模型对象→对象.save()
book = BookInfo(
btitle="西游记",
bpub_date="1998-1-1",
bread=10)
book.save()
# 2.模型类.objects.create(...)
hero = HeroInfo.objects.create(
hname="沙僧",
hcomment="你挑着担",
hbook=book)
更新的2种方式:
>>> hero = HeroInfo.objects.get(id=2)
>>> hero.hname = '猪悟能'
>>> hero.save()
HeroInfo.objects.filter(过滤条件).update(更新数据)
>>> res = HeroInfo.objects.filter(id=3).update(hname='沙悟净')
删除的2种方式:
>>> hero = HeroInfo.objects.get(id=3)
>>> hero.delete()
HeroInfo.objects.filter(过滤条件).delete()
>>> HeroInfo.objects.filter(id=2).delete()
models.py设置以下代码,定义每个数据对象的显示信息:
def __str__(self):
"""定义每个数据对象的显示信息"""
return self.btitle
使用tests.py测试查询,需要以下设置:
import os
if not os.environ.get('DJANGO_SETTINGS_MODULE'):
os.environ.setdefault("DJANGO_SETTINGS_MODULE","demo.settings")
import django
django.setup()
# 导入模型
from booktest.models import BookInfo,HeroInfo
if __name__ == "__main__":
print(BookInfo)
# 模型类.objects.
# get(查询条件):返回一个模型对象,如果查不到,会报错
book = BookInfo.objects.get(id=1)
# all():无参数,返回查询到的所有数据
books = BookInfo.objects.all() # QuerySet查询集:可以跟list一样操作
# count():无参数,返回查询到的结果数量
count = BookInfo.objects.count()
# get(查询条件):返回一个模型对象,如果查不到会报错
book = BookInfo.objects.get(id__exact=1)
# filter(查询条件):返回根据条件查询到的结果,返回的是QuerySet
books = BookInfo.objects.filter(btitle__contains="传") # 包含
books = BookInfo.objects.filter(btitle__startswith="天") # 以天开头
books = BookInfo.objects.filter(btitle__endswith='部') # 以部结尾
books = BookInfo.objects.filter(btitle__isnull=False) # 标题不为空
books = BookInfo.objects.filter(id__in=(1,3,5)) # 查询id为1,3,5的图书
# gt 大于,gte 大于等于,lt 小于,lte 小于等于
books = BookInfo.objects.filter(id__gt=3) # 查询id 大于3的图书
# exclude(查询条件):查询不满足条件的结果数据,返回的是QuerySet
books = BookInfo.objects.exclude(id=3) # 查询id不等于3的图书
# 日期查询
# year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算
books = BookInfo.objects.filter(bpub_date__year=1980) # 查询1980年发表的图书
books = BookInfo.objects.filter(bpub_date__gt=date(1990, 1, 1)) # 该日期以后发表的图书
# F对象:用于查询字段之间的比较
from django.db.models import F
books = BookInfo.objects.filter(bread__gte=F("bcomment")) # 查询阅读量大于等于评论量的图书
books = BookInfo.objects.filter(bread__gt=F('bcomment') * 2)# 阅读量大于2倍评论量的图书
# Q对象:用户查询时条件之间的逻辑关系 与或非
# &表示逻辑与,|表示逻辑或 ,~表示非
from django.db.models import Q
BookInfo.objects.filter(Q(bread__gt=20)&Q(id__lt=3)) # 查询阅读量大于20,并且编号小于3的图书
BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3)) # 查询阅读量大于20,或编号小于3的图书
BookInfo.objects.filter(~Q(pk=3)) # 查询编号不等于3的图书
# Avg 平均,Count 数量,Max 最大,Min 最小,Sum 求和
from django.db.models import Sum,Avg,Max,Min,Count
count = BookInfo.objects.aggregate(Sum('bread')) # 返回dict: {'bread__sum': 136}
res = BookInfo.objects.aggregate(Count('id')) # 查询数量
# 排序 返回查询集QuerySet
books = BookInfo.objects.order_by('bread') # 按照阅读量从小到大进行排序
books = BookInfo.objects.order_by('-bread') # 按照阅读量从大到小进行排序
# 1.查询和西游记关联的英雄人物信息
book = BookInfo.object.get(btitle='西游记')
heros = book.heroinfo_set.all()
# 2.查询id为1的图书关联的英雄人物信息
book = BookInfo.objects.get(id = 1)
heros = book.heroinfo_set.all()
# 3.查询id为1的英雄人物关联的图书信息
hero = HeroInfo.objects.get(id = 1)
book = hero.hbook
# 4.查询和孙悟空关联的图书信息
hero = HeroInfo.objects.get(hname ='孙悟空')
book = hero.hbook
查询和对象关联的数据:
BookInfo(一类)
HeroInfo(多类)
一对多:HeroInfo类中有一个外键关联属性:hbook = models.ForeignKey(BookInfo)
查询和图书对象关联的英雄数据(由一查多):
例子:heros = book.heroinfo_set.all()
一类对象.多类名小写_set.all()
查询和英雄关联的图书数据(由多查一):
例子:book=hero.hbook
多类对象.关联属性
以下函数返回的都是查询集:
all():返回所有数据。
filter():返回满足条件的数据。
exclude():返回满足条件之外的数据。
order_by():对结果进行排序。
查询集可以像list一样进行操作:遍历。取下标,切片(查询集切片时下标不能为负),QuerySet对象可以继承调用上面任何查询相关方法。
BookInfo.objects.filter(id__gt=3).order_by('bread')
QuerySet对象还有一个方法叫:exists→判断查询集中是否有数据,有返回True,没有返回Flase
两大特点:
惰性查询:只有在使用查询集中的数据时才会真正发生数据库的查询
数据缓存:使用同一个查询集中的数据,只有第一次使用的时候会查询数据库,然后会将查询的结果保存起来,
再使用这个查询集时,使用的时保存起来的数据,不会再去查数据库。
Django自带admin站点管理功能。
python manage.py createsuperuser
在子应用admin.py文件中注册模型类
admin.site.register(模型类)
自定义Admin站点管理页面
1.定义模型Admin管理类 admin.py
class BookInfoAdmin(admin.ModelAdmin):
# Django提供了很多类属性,通过对应的属性就可以控制管理界面对应内容的展示
# 显示哪些字段或方法
list_display = ["id" , "btitle","pub_date"]
# 每页显示多少条
list_per_page=100
# 编辑页显示字段
fields = ['btitle', 'bpub_date']
# 分组显示编辑页字段(与编辑页显示字段冲突,只能写一种)
fieldsets = (
('基本', {'fields': ['btitle', 'bpub_date']}),
('高级', {
'fields': ['bread', 'bcomment'],
'classes': ('collapse',) # 是否折叠显示
}))
class HeroInfoAdmin(admin.ModelAdmin):
...
# 右侧栏过滤器
list_filter = ['hbook', 'hgender']
# 搜索框
search_fields = ['hname']
2.注册模型类时将模型类和Admin管理类对应起来
admin.site.register(BookInfo,BookInfoAdmin)
admin.site.register(HeroInfo,HeroInfoAdmin)
使用pub_date方法的相关models.py配置:
class BookInfo(models.Model):
...
def pub_date(self):
return self.bpub_date.strftime('%Y年%m月%d日')
# 设置方法那一列的字段描述
pub_date.short_description = '出版日期'
# 让方法对应的那一列支持排序
pub_date.admin_order_field = 'bpub_date'
关联对象
在admin.py文件中添加一下信息
from django.contrib import admin
admin.site.site_header = 'Monkey-文字LOGO'
admin.site.site_title = '前瞻网络-网站标题'
admin.site.index_title = '来了老弟!-首页标语'
打开models.py设置字段
image = models.ImageField(upload_to='booktest',verbose_name='图片', null=True)
然后进行数据库迁移
python manage.py makemigrations
python manage.py migrate
使用Admin站点保存图片,需要安装Python的图片操作包
pip install Pillow==4.1.0
指定Admin站点上传图片保存的目录
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")