学习Django看这一篇就够了

Django

    • 1. 一 、 环境的搭建
    • 1.1. 1.1 虚拟环境
    • 1.2. 1.2 创建Django工程
    • 二、 视图与路由
    • 三、 请求与响应
    • 3.3. 3.3 cookie
    • 3.4. 3.4 session
    • 4. 四、 类视图与中间件
    • 5.1. (一) 解决django跨域问题
    • 六、 模板
    • 七、 数据库
    • 八、 admin

本文为个人学习前后端分离开发 后端所学到的部分技术,内容中没有涉及到模板的具体使用,更多的是对视图views、路由urls和数据库的操作以及部分调整admin后台的操作。学习这些内容可以为开发api打好铺垫

1. 一 、 环境的搭建

1.1. 1.1 虚拟环境

1.1.1. 1.1 创建

• mkvirtualenv 环境名 -p python3 • python -m venv 环境名

1.1.2. 1.2 激活环境

• win: 环境名\Scripts\activate • linux: source 环境名/bin/activate

1.1.3. 1.3停止虚拟环境

• deactivate

1.1.4. 1.4 删除虚拟环境

• rmvirtualenv

1.1.5. 1.5 进入虚拟环境

• workon

1.1.6. 1.6 pip的部分操作

• pip install 安装依赖包
• pip uninstall 卸载依赖包
• pip list 查看已安装的依赖包
• pip freeze 冻结当前环境的依赖包

1.2. 1.2 创建Django工程

1.2.1. 1.1 安装Django

• pip install django==版本

1.2.2. 1.2 创建Django项目

• django-admin startproject 项目名

.
1.2.3. 1.3 跑Django项目

• python manage.py runserver

1.2.4. 1.4 创建子应用

• python manage.py startapp 子应用

二、 视图与路由

2.1. 2.1 定义路由的方式

2.1.1. 1. 总 • 所有的路由都定义在 项目的urls中 • url(r’^users/index/$’,views.index)
2.1.2. 2. 总 + 子

• 执行顺序

在settings中的ROOT_URLCONF指定项目urls
• 项目的urls指定了子项目的urls
• 子项目的urls指向具体视图

• 路由
• 总路由
• url(r’^users’,include(‘users.urls’))
• 子路由
• url(r’^index/$’, views.index)
2.1.3. 3. 子
• 总路由

url(r’^’, include(‘users.urls’))

• 子路由

• url(r’^users/index/$’,view.index)

2.2. 2.2 静态文件访问

2.2.1. 开发过程中,在settings文件中添加STATICFILES_DIRS • # 配置静态文件加载存储目录

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static_files'),
    os.path.join(BASE_DIR, 'static_files/img'),
]

2.2.2. 生产过程中

如果将来将项目部署上线后,django服务器不再提供对静态文件访问的支持,因为Django服务器是动态业务逻辑服务器,不擅长静态文件处理
需要将静态文件放到 nginx

三、 请求与响应

3.1 请求Request
3.1.1. 提取URL路径参数

• 使用正则表达式在URL中获取请求参数,Django会将提取的参数直接传递到视图的传入参数中,加形参。 •
url(r’[a-z]+/\d{4}/KaTeX parse error: Undefined control sequence: \d at position 79: …-z]+)/(?P\̲d̲{4})/’, views.tianqi),

3.1.2. 提取GET属性的数据 Django中的QueryDict对象,即是 request.GET属性

• 与字典不同,QueryDIct对象用来处理同一个键带有多个值的情况 • get方法,有多个值的情况获取最后一个值
• querydict.get(‘键’) • getlist() 方法,值以列表的返回,如果键不存在返回空列表
• querydict.getlist(‘键’)

3.1.3. 提取POST属性的表单数据,request.POST属性,也是一个queryDict对象

• POST属性也是queryDict的对象,同样有get()与geilist()方法

3.1.4. 获取请求体非表单数据, request.body属性 获取的是一个 bytes类型的数据,需要进行转换

• json_str = json_bodys.decode() 方法 将bytes类型的数据转换成 json字符串
• json_dict = json.loads(json_str) 方法 将 json字符串转换成json字典或json列表
• json_str = json.dumps(json_dict) 方法将json字典转换成json字符串

3.1.5. 获取请求头数据request.META属性为字典类型

可通过request.META[‘CONTENT_LENGTH’]直接获取,或者request.META.get(‘HTTP_HOST’) 常见请求头
CONTENT_LENGTH 请求正文的长度(作为字符串)
CONTENT_TYPE 请求正文的MIME类型。
HTTP_ACCEPT 响应的可接受内容类型。
HTTP_ACCEPT_ENCODING - 响应的可接受编码。
HTTP_ACCEPT_LANGUAGE响应的可接受语言。
HTTP_HOST - 客户端发送的HTTP主机头。
HTTP_REFERER - 引用页面(如果有)。
HTTP_USER_AGENT - 客户端的用户代理字符串。
QUERY_STRING - 查询字符串,作为单个(未解析)字符串。
REMOTE_ADDR - 客户端的IP地址。
REMOTE_HOST - 客户端的主机名。
REMOTE_USER Web服务器验证的用户(如果有)。 •
REQUEST_METHOD - 诸如“GET”或“POST”之类的字符串。
SERVER_NAME - 服务器的主机名。
SERVER_PORT - 服务器的端口(作为字符串)。
• 除了上面给出的CONTENT_LENGTH和CONTENT_TYPE之外,请求中的任何HTTP头都将转换为META密钥,方法是将所有字符转换为大写,用下划线替换任何连字符,并在名称中添加HTTP_前缀。因此,例如,名为X-Bender的标头将映射到META密钥HTTP_X_BENDER。

3.1.6. request的其他属性
• method

一个字符串,表示请求使用的HTTP方法,例如 GET或者POST

• user

• 请求的用户对象,例如AnonymousUser

• path

一个字符串,表示请求页面的完整路径,不包括域名和参数部分

• encoding

一个字符串,表示提交数据的编码方式,一般事utf-8 • 如果为NOne,表示为浏览器的米热设置,一般为utf-8
• 这个属性是可写的,可通过修改它来访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值

• FILES

类似于字典的对象,包含所有的上传文件

3.2. 3.2 响应response
3.2.1. 在试图函数返回 HTTPRESPONSE()

• return HttpResponse(content=‘hello seven’,
content_type=‘text/html’, status=201)
• 其中contet写的返回的内容,content_type为返回的类型,status为返回的状态码

3.2.2. JsonResponse(dict,safe=True)

• dict处尽量是字典,否则可以会报错,可以指定safe参数为Flase,这样会将数据包成字典进行返回

3.2.3. 重定向 redirect

• 首先在视图函数内导入 redirect
• from django.shortcuts import redirect
• 在视图函数中 写 return redirect("/user/index")
• 假如写入的重定向路径开头没/ 则会在当前路径下直接重定向,假如写了/ 则会在根路径下进行跳转

3.2.4. 反向解析 reverse

• 在子应用的urls中为路由指定name,这种情况会发生,多个子应用如果别名相同的话,可能只解析到一个子应用的路由,因此我们需要在项目的urls中为每个子应用的路由添加命名空间
• 例如 url(r’^response_json/$’, views.response_json, name=‘json’), •
• 为子应用的路由添加命名空间 • 语法格式为
path(‘url地址’,include((‘app的url文件地址’,子应用文件名),namespace=‘命名’)

•	例如  path(r'weather/', include(('request_response.urls','request_response'), namespace='request_response')),
]

这样在使用反向解析的时候 语法为:
reverse(‘命名空间:别名’),
例如: reverse(‘user:json’)

3.3. 3.3 cookie

3.3.1. ookie介绍

• Cookie是存储在浏览器中的一段纯文本信息,尽量不要存储密码等敏感信息
• cookie 以键值对的格式进行信息的存储
• cookie基于域名安全,不同域名的cookie是不可以相互访问的
• 当浏览器请求某网站时,会将浏览器存储的跟网站相关的所有cookie信息提交给网站服务器

3.3.2. cookie使用

• 设置cookie
• 通过HTTPResponse中的set_cookie方法来设置cookie
• response = HTTPResponse(‘ok’) response.set_cookie(‘键’,‘值’, ''cookie生存时间)
• 访问cookie
• 通过 请求对象resquest.COOKIE.get(‘键名’)的得到对应的cookie值
• cookie_name = request.COOKIES.get(‘name’)
• 删除cookie
• 响应对象response.delete_cookie(‘键名’)
• response.delete_cookie(‘age’)

3.4. 3.4 session

3.4.1. 存储方式
• 内存

SESSION_ENGINE = “django.contrib.sessions.backends.cache”

• 数据库,需要在INSTALLED_APPS中安装Session应用,默认配置文件有

• SESSION_ENGINE = “django.contrib.sessions.backends.db”

• 混合存储

• SESSION_ENGINE = “django.contrib.sessions.backends.cache_db”

3.4.2. Redis内存型数据库
• 安装

• pip install django-redis redis

• 在django的setting中配置

# redis数据库配置
CACHES = {
     
    "default": {
     
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://49.232.23.70:6379/1",
        "OPTIONS": {
     
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

#设置session有内存缓存

SESSION_ENGINE = "django.contrib.sessions.backends.cache"

缓存到redis default的配置redis

SESSION_CACHE_ALIAS = "default"

3.4.3. session 的基本操作

• 键值对格式写session
• request.session[‘键’] = 值
• 根据键值取值
• request.session.get(‘键’)
• 删除session 中数据
• request.session.clear()
• 清除所有session 在储存中删除session的整条数据,包括cookie的session_id
• request.session.flush()
• 删除指定的键值,在存储中删除某个键对应的值
• del request.session[‘键’]
• 设置 session的有效期
• request.session。set_expiry(value)

  • 如果 value 是整数1,就是这只在value秒之后过期
  • 如果 value为0,那么浏览器关闭后sessionguo过期
  • 如果为None,在默认两周后过期,通过setting.py中的SESSION_COOKIE_AGE来设置

4. 四、 类视图与中间件

4.1. 类视图
4.1.1. 1. 导包

from django.views.generic import View 或者 from django.views import
View

4.1.2. 2. 写类

继承View 重写View类的get与post方法

4.1.3. 3

. 类试图的路由格式,url(r’^demoview/$’, views.类名.as_view()) • as_view()是判断请求方法的

4.1.4.

  1. 装饰器装饰类试图

• 装饰器代码

#装饰器
def my_decorator(view_func):
    '''定义装饰器'''
    def wrapper(request, *args, **kwargs):
        print('装饰器被调用了')
        return view_func(request, *args, **kwargs)
    return wrapper

• 在路由界面进行装饰

url(r'^demoview/$', views.my_decorator(views.ClassView.as_view()))

• 在类试图上进行装饰
• 导包

from django.utils.decorators import method_decorator

• 在类上面装饰类中的某个方法

@method_decorator(‘装饰器名字’, ‘需要被装饰的方法’)

• 例子@method_decorator(my_decorator,'dispatch')

这样装饰的效果就是将装饰方法转换成装饰函数,因为方法有一个self的属性

• 在类里面单独装饰某个方法

直接在方法名上写

@method_decorator(my_decorator)

4.2. 中间件
4.2.1. 介绍

• Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或者输出,中间件的设计为开发者提供了一种无侵入式的开发方式,增强了django的健壮性,
• 我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预

4.2.2. 中间件的定义方法

• 在settings.py文件的MIDDLEWARE列表中注册中间件 • 写在下面,这个列表后期被反转了(后面的会先执行)
• 在工程同名文件下新建middleware.py文件,文件里为中间件 (定义一个中间件工厂函数,然后返回一个可以被调用的中间件
,中间件工厂函数需要接收一个可以调用的get_response对象)

from django.http import HttpResponse


def my_middleware1(get_response):
    print('init1111  被调用')

    def middlware(request):

        print('before request 111111被调用')
        response = get_response(request)
        print('after response11111 被调用')
        return response

    return middlware


def my_middleware2(get_response):
    print('init2222222  被调用')

    def middlware(request):

        print('before request22222 被调用')
        response = get_response(request)
        print('after response 2222222被调用')

        return response

    return middlware


def my_middleware3(get_response):
    print('init 3333333 被调用')

    def middlware(request):

        print('before request 33333333被调用')
        response = get_response(request)
        print('after response333333333 被调用')

        return response

    return middlware

• 执行顺序 类似一个递归的操作 • 请求在被处理之前 所有的中间件是自上而下的去执行
• 当请求被处理之后响应时,所有的中间件的执行顺序是自下而上的
• 假设在中间件的返回response处写了一个固定返回,那么返回的界面就被这个固定的返回界面拦截了

def my_middleware2(get_response):
    print('init2222222  被调用')

    def middlware(request):

        print('before request22222 被调用')
        response = get_response(request)
        print('after response 2222222被调用')

        return HttpResponse('我拦截了所有的界面')

    return middlware

5.1. (一) 解决django跨域问题

5.1.1. 1. 安装

pip install django-cors-headers

5.1.2. 2. 配置 settings.py文件

#	在INSTALLED_APPS里添加
“corsheaders”
INSTALLED_APPS = [
...
'corsheaders'
]
#	在settiongs 里 MIDDLEWARE 中添加如下
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
]

5.1.3. 3. 在settings.py的末尾添加

	#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = ()
 
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)
 
CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)

六、 模板

6.1. 创建模板的步骤

  1. 在子应用目录下创建templates文件夹,存放html文件
  1. 在settings.py的模板文件配置项TEMPLATES的‘DIRS’中写入模板文件夹的路径 • 例如: ‘DIRS’: [os.path.join(BASE_DIR, ‘user/templates’)], #指定模板文件加载路径

  2. 在视图函数内返回 return render(request, ‘index.html’, context)
    其中context为字典数据 context = {
    ‘name’:‘kobe’,
    ‘userlist’:[8,24],
    ‘userdict’:{
    ‘age’: 20,
    ‘name’:‘詹姆斯’,
    } }

七、 数据库

7.1. ORM框架
7.1.1. 1. ORM框架

• O是 object
也就是类对象的意思,R是relation也就是关系,关系数据库中数据表的意思,M是mapping是映射的意思。它帮我们的类和数据表进行一个映射。可依让我们通过类和类对象就能操作它对应表格中的数据,它也可以根据我们设计的类自动帮我们生成数据库中的表格,省去我们建表的过程

7.1.2. 2. 使用django进行数据库开发步骤

• 配置数据库连接信息
• python3 安装 mysql3
• pip install pymysql
• 因为 在 ORM里面它只认识python2的 mysqldb 所以我们需要骗一下系统

• 具体操作:在工程文件里的init里加入如下代码:

import pymysql

pymysql.version_info = (1, 4, 13, "final", 0)  # 指定版本
pymysql.install_as_MySQLdb()   #将pymysql改别名为 mysqldb

• 1.3 创建一个数据库

• create database 数据库的名称 charset=utf8

• 1.4 在项目文件下的settings中配置数据库

	#数据库配置项
DATABASES = {
     
    'default': {
     
        'ENGINE': 'django.db.backends.mysql',
        'HOST':'49.232.23.70',    # 数据库主机
        'PORT':'3306',  # 端口号
        'USER':'root',  # 数据库用户名
        'PASSWORD':"seven597", # 数据库密码
        'NAME':'django_24',    # 数据库名
    }
}

• 2.2 在models.py中定义模型类
• 2.1 数据库表名

模型类如果未指明表名,Django默认 以小写app应用名_小写模型类名
为数据库表名,可以在模型类的Meta类中的db_table指明数据库表名

• 2.2 关于主键

• django
会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后django不会再创建自动生长的主键列。
• 默认创建主键列属性为id,可以使用pk代替,pk全拼为primary key

• 2.3 属性命名限制

• 不能是python的保留关键字 • 不允许使用连续的下划线,这是由django的查询方式决定的
• 定义属性时需要指定字段类型,通过字段类型的参数指定选项 语法如下: 属性 = models.字段类型(选项)

• 2.4 字段的类型

• AutoField 说明: 自动增长的IntegerField, 通常不用指定,不指定时django会自动创建名为id的自动增长属性
• BooleanField 说明:布尔字段,值为True或False
• NullBooleanField 说明: 支持Null、True、False
• CharField 说明:字符串,参数max_length表示最大字符个数
• TextFiled 说明:大文本字段,一般超过4000个字符的时候使用
• IntegerField 说明: 整数
• DecimalField 说明: 十进制浮点数,参数max_digits表示总数位数,参数decimal_places表示小数位数
• FloatField 说明:浮点数
• DetaField 说明:日期,参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于“最后一次修改”的时间戳,它总是使用当前日期,默认为False;参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False;参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
• TimeField 说明:时间,参数与DateField相同
• DateTimeField 说明:日期时间,参数同DateField • FileField 说明:上传文件字段
• ImageField 说明:继承于FileField,对上传的内容进行校验,确保上传的是有效图片

• 2.5 选项

• null 说明: 如果是True表示允许为空,默认值为False
• blank 说明:如果为True,则该字段允许为空白,默认为False
• null是数据库范畴的概念,blank是表单验证范畴的
• db_column 说明:字段的名称,如果未指定,则使用属性的名称
• db_index 若值为True,则在表中会为此字段创建索引。默认为False
• default 说明: 默认
• primary_key 说明: 若为True,则该字段会成为模型的主键字段。默认为false,一般作为AutoField的选项
• unique 说明:如果为True,这个字段在表中必须有唯一值,默认值为False

• 2.6 外键

• 在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含如下可选常量
• CASCADE级联,删除主表数据时,联通一起删除外键表中的数据
• PROTECT保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据
• SET_NULL设置为NULL,仅在该字段null=True允许为null时使用
• DO_NOTHING不做任何的操作,如果数据库前置指明级联性,此选项会抛出IntegrityError
• SET_DEFAULT设置为默认值,仅在该字段设置了默认值时可用 • SET()设置为特定值或者调用特定方法,如下

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models

def get_sentinel_user():
    return get_user_model().objects.get_or_create(username='deleted')[0]

class MyMqdel(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete = models.SET(get_sentinel_user)
    )

• 2.3 迁移

• 首先要注册子应用,迁移的话必须注册子应用
• 生成迁移文件: pyton manage.py makemigrations
• 同步到数据库: python manage.py migrate

• 2.4 通过类和对象完成数据的增删改查操作
7.1.3. 3. 演示工具
• shell工具

• python manage.py shell

• 查看Mysql数据库日志
• 进入数据库的配置文件

• sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

• 设置如下两行代码

• general_log_file = /var/log/mysql/mysql.log • general_log = 1

• 重启数据库

• sudo service mysql restart

• 实时查看数据库的日志

• sudo tail -f /var/log/mysql/mysql.log

7.1.4. 4. 数据库操作之增删改查
• 4.1 增 save()
• 首先引入 models.py

book = BookInfo()
book.字段 = '值'
book.save()方法

• 当第二个表有外键的时候,关联第一个表的主键

hero = HeroInfo(
    字段 = '值',
    外键 = 主键的属性 或者 外键_id = 主键所在表的属性.id)

例如 hbook = book 或者 hbook_id = book.id

)

• create()

类名.objects.creats(
    字段=‘值’
)

蕴含了save()方法

• 4.2 查
• 基本查询
• get()

类名.objects.get(id=?)

例如

try:
    BookInfo.objects.get(id=15)
except BookInfo.DoesNotExist:
    print('查询失败')

加上异常语句,如果找不到id的话会出异常

• all()

• 类名.pbjects.all()

例如: HeroBook.objects.all()

会查询所有的记录,返回一个 QuerySet

• 过滤查询
• filter()

过滤出多个结果 过滤条件的语法是 属性名__比较运算符=值

• exact :表示判等

• BookInfo.objects.filter(字段__eaact = ‘值’)

例子: HeroInfo.objects.filter(hbook_id__exact=2)

说明: 查询字段为 某值的记录,可以查询多个记录,返回QuerySet,即使查询的字段值不存在也不会报错

• contains:表示是否包含 •

BookInfo.objects.filter(字段__contains == ‘值’)

例:

 HeroInfo.objects.filter(hname__contains='黄')

说明:查询某字段中包含某值的记录,返回多条记录(QuerySet)

• startswith,endswith:以指定值开头或结尾

# 查询 以...结尾的
BookInfo.objects.filter(btitle__startswith='西')
 查询 以...开头的
BookInfo.objects.filter(btitle__endswith='国')

• isnull:是否为null

BookInfo.objects.filter(btitle__isnull=False)

• 多项查询,in:是否包含在指定项内
• #查询编号为 n 或者 m 的

BookInfo.objects.filter(id__in = [2, 4])

• 比较查询
• gt 大于, gte 大于等于, lt 小于, lte小于等于
• #查询编号大于2的

BookInfo.objects.filter(id__gt = 2)

#查询编号大于等于2的

BookInfo.objects.filter(id__gte = 2)

#查询编号小于4的

BookInfo.objects.filter(id__lt = 4)

#查询编号小于等于4的

BookInfo.objects.filter(id__lte = 4)

• 不等于运算器,使用exclude(id=3)过滤器
• # 查询 id 不为 …的

BookInfo.objects.exclude(id=3)

• 日期查询
• year,month,day,week_day,hour,minute,second
• #查询1995年,11月的发布的书籍,

BookInfo.objects.filter(bpub_date__year='1995', bpub_date__month='11')

#查询1990年1月1日后发布的书籍

BookInfo.objects.filter(bpub_date__gt='1990-1-1')

• F对象与Q对象

• 引用头文件 from django.db.models import F,Q

• F对象进行两个属性之间进行比较,也支持运算操作

BookInfo.objects.filter(bread__gt=F('bcomment'))
BookInfo.objects.filter(bread__gt=F('bcomment') * 2)

• Q对象:逻辑与 逻辑或 逻辑非 and or not

BookInfo.objects.filter(bread__gt=11, id__lt=3)
BookInfo.objects.filter(Q(id__lt=3) | Q(bread__gt=20))
BookInfo.objects.filter(~Q(id__lt=3))

• 聚合函数

使用aggregate()过滤器调用聚合函数

• Avg平均

from django.db.models import  Sum, Avg,Count,Max,Min

• 排序查询
• # 升序

BookInfo.objects.all().order_by('bread')

#降序

BookInfo.objects.all().order_by('-bread')

• 关联查询

• 举例 : # 书的表为主键所在表,英雄的表存在一个外键存储书的id • 多查一,通过即有外键的表查询外键关联的表
• #多查一,根据英雄查询这个英雄属于哪本书

BookInfo.objects.filter(heroinfo__hname='郭靖')
BookInfo.objects.filter(heroinfo__hname__contains='竹')

• # 根据英雄查书, 多查一

hero = HeroInfo.objects.get(hname='郭靖')
book = hero.hbook       #如果有外键直接当前模型对象, 外键代表获取外键模型对象

• 一查多,是通过外键关联的表(主键表)查询外键的所有值

#一查多
HeroInfo.objects.filter(bookinfo__id=1)   不可以用这种方法
HeroInfo.objects.filter(hbook__id=1)

• #根据书查英雄,一查多

book = BookInfo.objects.get(id=1)
heros = book.heroinfo_set.all()  # 如果当前没有外键的一方, 应该是当前模型对象多的一方模型小写_set 获取所有应当加_set.all()

• 4.3 删
• delete()

#单个删除
BookInfo.objects.get(btitle='大大三国').delete()
#多个删除
BookInfo.objects.filter(id=8).delete()

• 4.4 改
• save()方法

book = BookInfo.objects.get(btitle='大三国')
book.btitle = '大大三国'
book.save()

update()方法

BookInfo.objects.filter(btitle='西游记').update(btitle='东游记')

7.1.5. 查询集 QuerySet
• 概念

• QuerySet 表示从数据库中获取的对象集合,当调用如下过滤器的时候,返回的是查询集,而不是简单的列表。 all()
filter() exclude() order_by() • 对于QuerySet的数据,可以再次使用查询集

例如: BookInfo.objects.filter(bread__gt=30).order_by('bpub_date')
• 限制查询集

• 可对查询集进行去下标或者切片的操作,等同于sql中的limit和offset子句

qs = BookInfo.objetcs.all()[0:2]
#也可以取步长 
HeroInfo.objects.all()[0:10:2]

八、 admin

8.1. 1. 创建超级管理员

python manage.py createsuperuser

8.2. 2. py文件对应的admin后台
8.2.1. apps文件里,name与子应用名字一样,verbose_name为admin里显示的模型组的名字

from django.apps import AppConfig


class BooktestConfig(AppConfig):
    name = 'booktest'
    verbose_name = '图书'

8.2.2. models.py

• 使用 admin.site.register(模型名字)

• 代码:

from django.contrib import admin

from .models import BookInfo,HeroInfo
 Register your models here.
admin.site.register(BookInfo)
admin.site.register(HeroInfo)

8.3. 3. 定义模型站点管理类调整admin站点样式

创建BookInfoAdmin(admin.ModelAdmin) 继承admin的ModelAdmin类,在这个类里面管理模型列表界面

8.3.1. 显示隐藏底部搜索框

actions_on_bottom =True 为显示底部搜索框

8.3.2. 控制列表界面显示模型对应的哪些字段(元素可以是模型中的方法名,字段名),假如我们想格式化显示,可以在模型类中添加对应的方法,将方法名放在这个列表中
• models的模型来中定义的方法

def bpub_date_format(self):
    return self.bpub_date.strftime('%Y-%m-%d')
bpub_date_format.short_description = "发布日期"  #修改方法名在列表页展示成中文
bpub_date_format.admin_order_field = 'bpub_date' #此方法中的数据依据模型的那个字段进行排序

• admin 的站点管理类中加入代码

list_display = ['id', 'btitle', 'bread_company', 'bcomment', 'is_delete', 'bpub_date_format']

8.3.3. 设置右侧过渡栏

list_filter = ['hbook', 'hgender']

8.3.4. 设置搜索框

 search_fields = ['hname', 'id']

8.3.5. 设置编辑界面显示的字段
• 只会显示列表中存在的字段

 fields = ['btitle', 'bpub_date']

• 将编辑字段分组展示,可设置默认隐藏显示

fieldsets = [
        ['基础组', {
     'fields':['btitle', 'bpub_date']}],
        ['高级组', {
     
                    'fields': ['bread', 'bcomment'],
                    'classes':['collapse']   #
        }]
    ]

8.3.6. 关联显示数据(在book中显示hero)
• 创建一个关联显示类,继承model.admin.TabularInline如下

class HeroInfoStack(admin.TabularInline):
    model = HeroInfo #关联的模型类
    extra = 2  # 显示几个空盒子

在 bookinfo的模型类中加入

inlines = [HeroInfoStack]

谢谢您的观看~
学习Django看这一篇就够了_第1张图片

你可能感兴趣的:(Python,后端,python,django,api)