Django

IntYou (^_^)

Django MVT

  • 网站设计的三层架构

  • 借鉴于Java的MVC(C: Controller)

M(Model数据模型: 数据层)V(View视图层: 控制层)T(Templete模板层(在MVC中为视图层))

创建Django工程文件

django-admin startproject 文件名

内部生成文件

  • manage.py 内置django命令

  • settings 配置文件

  • urls 路由文件

  • wsgi 网关系统 在互联网中可以被其他计算机访问的文件

运行Django工程

manage.py 内置测试服务器运行指令

python3 manage.py runserver (默认8000端口)

创建子应用

python3 manage.py startapp 应用名

内部生成文件

  • admin.py 与网站后台管理站点配置相关

  • apps.py 用于配置当前子应用的相关信息

  • mifrations 用于存储数据库迁移历史文件

  • models.py 用户保存数据库模型类

  • tests.py 用于开发测试用例,编写单元测试

  • views.py 用于编写web应用视图

Setting配置

  • ALLOWED_HOSTS = [‘*’] 允许访问的主机

  • INSTALLED_APPS = [‘app’] 应用注册,app在创建后在此注册应用

外键的优缺点

优点:

  • 由数据库自身保证数据一致性和完整性,数据更可靠

  • 可以增加ER图的可读性

  • 外键可以节省开发量

缺点:

  • 性能确实,有额外的开销

  • 主键表被锁定时,会引发外键表也被锁

  • 删除主键表的数据时,需先删除外键表的数据

  • 修改外键表字段时,需重建外键约束

  • 不能用于分布式环境

  • 不容易做到数据解耦

应用场景

  • 适用

    内部系统,传统企业级,规模可控的环境

  • 不适用

    规模不可控的环境, 数量大

on_delete:

  • models.SET_NULL
    置空模式,删除时,外键字段被设置为空,前提就是blank=True, null=True,定义该字段时,允许为空。理解:删除关联数据(子表),与之关联的值设置默认值为null(父表中),这个前提需要父表中的字段可以为空。
    PS:外键写在多处,且写外键只能是主键,如没设置主键,django会自动帮你创

  • None:
    删除关联表的数据时,当前表与关联表的filed的行为。

  • models.CASCADE:
    表示级联删除,当关联表(子表)中的数据删除时,与其相对应的外键(父表)中的数据也删除。

  • models.DO_NOTHING:
    你删你的,父亲(外键)不想管你

  • models.PROTECT:
    保护模式,如采用这个方法,在删除关联数据时会抛出ProtectError错误

  • models.SET_DEFAULT:
    设置默认值,删除子表字段时,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。

  • on_delete = models.SET(值):
    删除关联数据时,自定义一个值,该值只能是对应指定的实体

视图

  1. 视图函数必须定义一个参数(通常命名为request)

    • request: 用来接收客户端的请求信息的
  2. 视图函数的返回值必须是一个HttpResponse的对象

视图使用的流程

  1. 在应用的views.py定义视图函数

  2. 配置路由

    • 在项目目录的urls.py中关联应用下的urls.py

    • 在应用的目录下定义一个urls.py文件

    • 配置具体的访问规则

      urlpatterns = [path('路由名', 包路径)]

admin Django默认后台

  1. 配置admin账户密码

    • python manage.py createsuperuser

模板

模板的配置和使用步骤:

  1. 在项目目录下创建一个templates文件夹

  2. 在setting.py中TEMPLATES选项中配置项目模板的根路径

    'DIRS': [BASE_DIR / 'templates']

  3. 在templates中创建和应用同名文件夹

  4. 在templates下应用同名的文件夹中创建html模板页面

  5. 在views.py中定义视图函数, 并返回html模板页面

    • 参数:

      • 第一个请求对象

      • 第二个模板路径

      • 第三个要渲染到模板中的数据(必须是字典)

    return render(request, 'news/list.html', info)

  6. 配置路由访问规则

修改数据库为MySQL

1
2
3
4
5
6
7
8
9
10
11
# 修改为:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '',
'USER':"",
'PASSWORD':"",
'HOST':"127.0.0.1",
'PORT': 3306
}
}

创建模型

  1. 调用from Django.db import models

  2. 创建模型类class 模型名(models.Model)

  3. 设置属性

  4. 表名自定义:

    1
    2
    3
    4
    5
    6
    class 模型名(models.Model):
    class Meta:
    # set the table's name
    db_table = 'newinfo'
    # set the table's info
    verbose_name = "new's info"

模型表迁移

python manage.py makemigration

python manage.py migrate

自定义admin后台

  1. 进入admin.py

  2. 新建类class admin类(admin.ModelAdmin)

  3. 将模型中的属性都放入admin类中的list_display中

    list_display = ['id', 'name']

  4. 注册绑定类admin.site.register(模型名,admin模型名)

模型类的查询方法

精确查询

  • get方法: 查询一条数据

    查询id为1的数据

    NewsType.object.get(id=1)

    特点: 只能查询唯一满足条件的数据

    没有找到符合条件的数据,直接报错(DoesNotExist)

    查询出多条符合条件数据,也会报错(MultipleObjectReturned)

  • filter方法: 根据条件过滤查询

    返回的值是一个quertSet对象(查询集)

  • all方法: 返回模块类对应的表中所有数据

    返回的值是一个querSet对象(查询集)

  • exclude方法: 查询不符合条件的数据

    查询name不是实时政治的

    NewsType.object.exclude(name='实时政治')

  • order_by: 排序方法

    根据新闻的阅读量进行排序(升序)

    NewsInfo.object.all().order_by('read')

    (降序)

    NewsInfo.object.all().order_by('-read')

    • 排序规则:

      默认是从小到大(升序)

      降序排序在字段前面加一个’-‘

  • 查询集:

    • 支持索引取值

    • 支持切片

    • 支持再次调用查询方法

模糊查询

条件语法格式:

  • 模型类.object.filter(模型类属性名__条件名=值)
  • 包含: contains
1
2
# 查询名称里包含'娱乐'的新闻类别
NewsInfo.objects.filter(new_type__contains='娱乐')
  • 开头: startswith
1
2
# 查询以'国'开头的新闻类别
NewsInfo.objects.filter(new_type__startswith='国')
  • 结尾: endswith
1
2
# 查询以'资讯'结尾的新闻类别
NewsInfo.objects.filter(new_type__endswith='资讯')
  • 范围查询: in
1
2
# 查询id为1或3或5的新闻类别
NewsInfo.objects.filter(id__in=[1, 3, 5])

比较查询

  • 大于: gt

  • 小于: lt

  • 大于等于: gte

  • 小于等于: lte

  • 字段值是否为Null: isnull

    查询name不为空的字段

    NewsType.objects.filter(name__isnull=False)

F对象和Q对象

  1. F对象: 用来比较查询数据的两个属性

    导入: from django.db.models import F

    查询 ‘阅读量’ 大于 ‘评论数量’两倍的新闻

    NewsInfo.objects.filter(read__gt=F('comment')*2)

    F对象查询结果可以直接进行算数运算

  2. Q对象: 逻辑查询(与或非)

    导入: from django.db.models import Q

    1. 逻辑与:

      不使用Q对象:

      查询阅读数量大于40,评论数量大于35的数据

      NewsInfo.objects.filter(read__gt=40,comment__gt=35)

      使用Q对象:

      NewsInfo.objects.filter(Q(read__gt=40) & Q(comment__gt=35))

    2. 逻辑或:

      NewsInfo.objects.filter(Q(read__gt=40) | Q(comment__gt=35))

    3. 逻辑非:

      通过 exclude查询:

      NewsType.object.exclude(name='实时政治')

      通过Q对象:

      NewsType.object.exclude(~Q(name='实时政治'))

模型类关联查询

  1. 通过对象进行关联查询

    单一查询.模型类名_set.操作()

    由一到多的查询:

    1
    2
    b = BookInfo.objects.get(id=1)
    b.hero_set.all()

    由多到一的查询:

    1
    2
    b = BookInfo.objects.get(id=1)
    b.book # 属性名
  2. 通过模型类进行关联查询

    由一到多的查询:

    关联模型类名小写__属性__比较方法 = 值

    1
    Book.objects.filter(hero__name__contains='峰')

    由多到一的查询:

    关联字段__属性__条件运算符 = 值

    1
    Hero.objects.filter(book__name='天龙八部')

增删改操作

添加数据

通过模型类往数据库添加数据

1
2
3
4
5
6
Book.objects.create(title='新闻001') # 方式一

# 方式二
obj = Book()
obj.title = '啦啦啦'
obj.save()

删除数据

1
2
obj = Book.objects.get(title='xxx')
obj.delete()

修改数据

通过模型类修改数据

1
2
3
obj = Book.objects.get(title='xxx')
obj.title = 'yyy'
obj.save()

路由

项目下的 urls.py 是整个项目路由匹配的入口

添加路由

将应用中的 urls.py 的引入主 urls.py

1
2
3
4
5
from django.urls import path, include
urlpatterns = [
path('news/', include('news.urls')),
path('book/', include('book.urls'))
]

url参数

  • 方式一:位置参数

    直接使用小括号,通过位置参数传递给视图

    1. 参数匹配

      1
      re_path(r'^index/(\d+)/$',views.show)
    2. 视图中获取参数

      1
      2
      def show(request, num):
      return HttpResponse(f'aaaaa{num}')
  • 方式二:关键字参数

    1. 参数匹配

      其中 ?P<name1> 表示为这个参数定义的名称为 name1,可以是其他名称

      1
      re_path(r'^index/(?P<name1>\d+)/$', show)
    2. 视图中获取参数

      1
      2
      def show(request, name1):
      return HttpResponse(f'aaa{name1}')

错误视图

Django 内置处理 HTTP 错误的视图,主要错误及视图包括:

  • 404错误:url 匹配失败,找不到页面

  • 500错误:server error 视图

如果想看到错误试图而不是调试信息,需要修改 setting.py 文件的 DEBUG 项

1
2
DEBUG = False
ALLOWED_HOSTS = ['*']
  1. 404错误视图配置

    将请求地址进行 url 匹配后,没有找到匹配的正则表达式,则调用 404 视图,这个视图会调用 404.html 的模板进行渲染。视图传递变量 request_path 给模板,表示导致错误的 URL

    1. 在 templates 中创建 404.html

    2. 在浏览器中访问没有定义的路由,触发错误

  2. 500错误视图配置

    在视图中代码运行报错会发生500错误,调用内置错误视图,使用 templates/500.html 模板渲染

    1. 定义错误的视图

    2. 访问错误的视图

HttpRequest 对象

  1. request 对象的属性

    • path:表示请求的页面的完整路径,不包括域名和参数部分

    • method:表示请求使用的 HTTP 方法,常用值包括:’GET’, ‘POST’

    • encoding:表示提交的数据的编码方式

    • FILES:包含所有上传文件

    • COOKIES:包含所有的 cookie,key 和 value 都是字符串

HttpResponse 对象

  1. 初始化参数

    • content:表示返回的内容字符串

    • charset:表示 response 采用的编码字符集,默认为 utf-8

    • status_code:返回的是HTTP响应状态码

    • content_type:指定返回数据的MIME类型,默认为’text/html’

重定向

当一个逻辑处理完成后,不需要向客户端呈现数据,而转到其他页面

  1. 定义视图

    1
    2
    3
    4
    5
    from django.http import HttpResponseRedirect

    # 定义重定向视图
    def red(request):
    return HttpResponseRedirect(redirect_to='/')
  2. 配置 url

    1
    url(r'^red/$', views.red)

简写redirect

1
2
3
from django.shortcuts import render,redirect
def red(request):
return redirect('/')

类视图

1
2
3
4
5
6
7
8
from django.views import View

class view(View):
def get(self, request):
pass

def post(self, request):
pass

在urls.py 中配置路由

1
re_path(r'xxx/$', view.as_view())

模板

1
2
3
4
5
6
7
8
from django.shortcuts import render

class IndexView(View):
def get(self, request):
context = {
'xxx' = 'xxx'
}
return render(request, 'tempdemo/index.html', context)

在urls.py中配置路由

  • 标题: Django
  • 作者: IntYou
  • 创建于: 2023-03-25 12:37:08
  • 更新于: 2023-04-30 19:27:50
  • 链接: https://intyou.netlify.app/2023/03/25/Django/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。