Django框架知识要点总结笔记

哪些请求方式在请求地址的时候可以带请求体?

只有PATCH、POST、PUT、DELETE访问一个url地址时可以带请求体

web框架和web服务器

在这里插入图片描述
web框架:flask Django

作用:

1.路由分发(根据url找到对应的处理函数)

2.调用处理函数进行业务处理。

web服务器 app.run()

作用:

1.解析请求报文,调用框架程序处理请求。

2.组织响应报文,返回内容给客户端。

web框架学习方法

  • 如何搭建工程程序

    工程的组建

    工程的配置

    路由定义

    视图函数的定义

  • 如何获取请求数据(操作request对象)

  • 如何构造响应数据(构造response对象)

  • 如何使用中间层

    请求钩子

  • 框架提供的其他功能组件

    数据库

    模板

    admin

Django简介

Django的主要目的是简便、快速的开发数据库驱动的网站。强调代码复用、快速开发和DRY(不要自己重复造轮子)原则。

特点

1.重量级框架

Django原生提供了众多的功能组件,让开发更简便快速。

  • 提供项目工程管理的自动化脚本工具
  • 数据库ORM支持(对象关系映射,英语Object Relational Mapping)
  • 模板
  • 表单
  • Admin站点
  • 文件管理
  • 认证权限
  • session机制
  • 缓存

2.MVT开发模式

Model(模型)-View(视图)-Template(模板)

Model,负责和数据库交互,进行数据处理

View,用于接收请求,处理业务逻辑

Template,负责封装构造要返回的html

其实和MVC框架一样

Django框架环境安装&项目创建

1)命令

mkvirtualenv name -p python3  # 创建虚拟环境
workon name # 进入虚拟环境
pip install django==1.11.11 # 安装django
cd 目录  # 切换目录
django-admin startproject <项目名称> # 创建项目
python manage.py startapp #创建子应用

2)进行子应用注册

点开项目目录下的settings,在INSTALLED_APPS中配置

在这里插入图片描述

3)启动

python manage.py runserver

定义视图函数

定义在子应用的views.py中

需要request接收请求并返回响应对象

def index(requset):
    """request:接收请求对象"""
    # 返回相应对象
    return HttpResponse('hello world')

URL配置

1) 在子应用中创建urls.py,设置子应用中url地址和视图函数之间的对应关系

from django.conf.urls import url
from users import views

urlpatterns = [
    # 添加当前子应用中url地址和视图函数之间的对应关系
    # url('地址url正则表达式','对应视图函数')
    url(r'index',views.index),
]

2)在项目总的urls.py文件中包含子应用中的urls.py文件

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'))
]

3)Django路由匹配过程说明

先找项目总的urls.py中正则匹配url地址,调用视图函数,再进入子应用中的urls.py进行正则匹配,调用视图函数
在这里插入图片描述

4) 路由配置时两个注意点:

子应用中进行url配置时,严格匹配开头和结尾

Django url 地址配置的默认风格时:末尾加/

url(r'^index/$', views.index)

5)Django路由配置-url地址的反向解析

总的应用中定义别名用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')

配置文件settings.py

1)BASE_DIR(根目录)

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

2)DEBUG

  • 修改代码文件,程序自动重启
  • Django程序出现异常时,向前端显示详细的错误追踪信息

3)中国语言与时区

在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' # 设置时区

4)静态文件的使用

在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')]

请求参数传递

4种传参方式

1.通过url地址传递参数(利用正则表达式提取参数的方法从url中获取请求参数)
#/weather/城市名/年份/:比如:/weather/shanghai/2019/
#flask: 路由转换器 /weather/<city>/<int:year>
#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<city>[a-z]+)/(?P<year>\d{4})/$', views.weather),

#在视图函数中获取
def weather(request, year, city):
    print('city=%s' % city)
    print('year=%s' % year)
    return HttpResponse('OK')
2.请求参数传递(通过查询字符串传参)
# /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')
    
3.通过请求体传递参数(json数据或表单)
表单数据:/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',
]
4.通过请求头传递参数
/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')

Django和flask中request对象属性对比

在这里插入图片描述

响应Response

响应对象的构造与说明

视图访问响应时返回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)

返回json数据(重点)

from django.http import JsonResponse
return JsonResponse({'name':monkey,'age',23})

状态保持

cookie的设置和获取

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储存说明

session:数据存储在服务器,以key-value进行存储。

特点: session依赖于cookie,每个客户端的session数据的标识存储到cookie中

flask session过期时间默认一个月,django session过期时间默认为2周。

session的三种储存方式

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'

session存储到redis设置

安装扩展 pip install django-redis

  1. 先将服务器缓存改为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"
  1. 再将session设置到缓存中

session的设置和获取

# /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))

session的操作

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扩展类

把一些通用的功能封装到不同的父类中,子类需要哪些功能,就可以继承哪些父类,这些父类就是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模板和jinja2模板使用对比

1){{模板变量}}

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>
2)条件判断

Django模板中在进行条件判断时,比较操作符的两边必须有空格

3)循环/判断

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 %}  # 错误
4)模板过滤器

{{模板变量|过滤器:参数}}

注: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秒"

4)注释

1)单行注释语法如下:

{#...#}

2)多行注释使用comment标签,语法如下:

{% comment %}
...
{% endcomment %}
5)模板继承
定义代码块:
{% block 名称 %}
预留区域,可以编写默认内容,也可以没有默认内容
{% endblock  名称 %}

子模版继承:
{% extends "父模板路径"%}

{% block 名称 %}
实际填充内容
{{ block.super }}用于获取父模板中block的内容
{% endblock 名称 %}

数据库

ORM框架

Django自带ORM框架:通过类和对象可以直接进行数据库操作,根据模型类自动生成表

数据库链接配置

  1. 使用MySQL数据库首先需要安装驱动程序

    pip install PyMySQL
    
  2. 在Django的工程同名子目录的__init__.py文件中添加如下语句

    from pymysql import install_as_MySQLdb
    
    install_as_MySQLdb()
    

    作用是让Django的ORM能以mysqldb的方式来调用PyMySQL。

  3. 修改DATABASES配置信息

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '127.0.0.1',  # 数据库主机
            'PORT': 3306,  # 数据库端口
            'USER': 'root',  # 数据库用户名
            'PASSWORD': 'mysql',  # 数据库用户密码
            'NAME': 'django_demo'  # 数据库名字
        }
    }
    
  4. 在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中包含了可选常量:

  • CASCADE 级联,删除主表数据时连通一起删除外键表中数据
  • PROTECT 保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据
  • SET_NULL 设置为NULL,仅在该字段null=True允许为null时可用

生成迁移文件

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)
基本查询-all&get&count
# 模型类.objects.
# get(查询条件):返回一个模型对象,如果查不到,会报错
book = BookInfo.objects.get(id=1)
# all():无参数,返回查询到的所有数据
books = BookInfo.objects.all() # QuerySet查询集:可以跟list一样操作
# count():无参数,返回查询到的结果数量
count = BookInfo.objects.count()
条件查询-get&filter&exclude
# 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对象&Q对象
# 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
    多类对象.关联属性

在这里插入图片描述

查询集QuerySet
以下函数返回的都是查询集:
all():返回所有数据。
filter():返回满足条件的数据。
exclude():返回满足条件之外的数据。
order_by():对结果进行排序。

查询集可以像list一样进行操作:遍历。取下标,切片(查询集切片时下标不能为负),QuerySet对象可以继承调用上面任何查询相关方法。
	BookInfo.objects.filter(id__gt=3).order_by('bread')
QuerySet对象还有一个方法叫:exists→判断查询集中是否有数据,有返回True,没有返回Flase

两大特点:
	惰性查询:只有在使用查询集中的数据时才会真正发生数据库的查询
    数据缓存:使用同一个查询集中的数据,只有第一次使用的时候会查询数据库,然后会将查询的结果保存起来,
    再使用这个查询集时,使用的时保存起来的数据,不会再去查数据库。

Admin管理

Admin站点管理的基本使用

Django自带admin站点管理功能。

1.语言和时区的本地化
2.创建管理员用户

python manage.py createsuperuser

3.APP应用配置

在这里插入图片描述

4.注册模型类

在子应用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站点标题设置

在admin.py文件中添加一下信息

from django.contrib import admin
admin.site.site_header = 'Monkey-文字LOGO'
admin.site.site_title = '前瞻网络-网站标题'
admin.site.index_title = '来了老弟!-首页标语'

Admin站点上传图片

打开models.py设置字段

 image = models.ImageField(upload_to='booktest',verbose_name='图片', null=True)
  • upload_to 选项指明该字段的图片保存在MEDIA_ROOT目录中的哪个子目录

然后进行数据库迁移

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")
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章