欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

3 Django 创建表关系 请求声明周期流程图 路由层

程序员文章站 2022-06-02 16:14:20
...

Django

1 ORM创建表关系

表与表之间的关系:一对多,多对多,一对一。
判断表关系的方法:换位思考。

案例:图书表,出版社表,作者表,作者详情表

图书表和出版社表是一对多的关系,外键字段建在多的一方,即图书表上;
图书表和作者表是多对多的关系,需要创建第三张表来存储两张表的外键字段;
作者表与作者详情表是一对一的关系,外键字段建在查询频率较高的一方,即作者表上。

1.1 创建表

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='书名')
    price = models.DecimalField(max_length=8, max_digits=2, verbose_name='价格')

class Publish(models.Model):
    name = models.CharField(max_length=32, verbose_name='出版社名')
    addr = models.CharField(max_length=128, verbose_name='出版社地址')

class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name='作者姓名')
    age = models.IntegerField(verbose_name='作者年龄')

class AuthorDetail(models.Model):
    phone = models.BigAutoField(verbose_name='手机号码')
    addr = models.CharField(max_length=128, verbose_name='居住地址')

1.2 创建表关系

图书表和出版社表是一对多的关系,外键字段建在多的一方,即图书表上。

class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='书名')
    price = models.DecimalField(max_length=8, max_digits=2, verbose_name='价格')
    public = models.ForeignKey(to='Public')  # 默认是与出版社表的主键字段做关联。

图书表和作者表是多对多的关系,ORM会自动创建第三张表,外键字段建在任意一方均可,推荐建在查询频率较高的一方。

class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='书名')
    price = models.DecimalField(max_length=8, max_digits=2, verbose_name='价格')
    public = models.ForeignKey(to='Public')
    authors = models.ManyToManyField(to='Author')
    # authors是一个虚拟字段,表明图书表和作者表是多对多的关系。

作者表与作者详情表是一对一的关系,外键字段推荐建在查询频率较高的一方,即作者表上。

class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name='作者姓名')
    age = models.IntegerField(verbose_name='作者年龄')
    author_detail = models.OneToOneField(to='AuthorDetail')

1.3 结果

app02_author
app02_authordetail
app02_book
app02_book_authors
app02_publish
auth_group
auth_group_permissions
auth_permission
auth_user
auth_user_groups
auth_user_user_permissions
django_admin_log
django_content_type
django_migrations
django_session

3 Django 创建表关系 请求声明周期流程图 路由层

1.4 总结

  1. ORM中如何定义三种关系
# 图书表和出版社表是一对多的关系,外键字段建在多的一方,即图书表上。
publish = models.ForeignKey(to='Publish')

# 图书表和作者表是多对多的关系,ORM会自动创建第三张表,外键字段推荐建在查询频率较高的一方,即图书表上。
authors = models.ManyToManyField(to='Author')

# 作者表与作者详情表是一对一的关系,外键字段推荐建在查询频率较高的一方,即作者表上。
author_detail = models.OneToOneField(to='AuthorDetail')
  1. 如果字段对应的是ForeignKey,ORM会自动在字段名后面添加后缀_id。

2 Django请求声明周期流程图

web服务网关接口
Django使用自带的wsgiref模块
作用:

  1. 收到请求时,对http协议格式的请求数据进行解析,并封装成字典格式;
  2. 发送响应时,将响应数据封装成符合http协议格式的数据。
    补充:
  3. wsgiref模块支持的并发量不大,最大并发量不超过1000;
  4. 项目上线后一般会换成uwsgi,前面还会加nginx进行反向代理;
  5. WSGI,wsgiref 和 uwsgi 是什么关系?
    WSGI是协议,wsgiref和uwsgi是实现该协议的功能模块。
    3 Django 创建表关系 请求声明周期流程图 路由层

3 路由层

3.1 路由匹配

urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'test', views.test),
    url(r'test123', views.test123),
]

url函数中第一个参数是正则表达式,
当访问 http://127.0.0.1:8000/test123 时,test123中包含test,可以匹配,
只要正则表达式能够匹配到内容,就会停止向下继续匹配,执行相应的视图函数test。
这意味着视图函数test123永远无法执行。

3.2 路由结尾添加正斜杠/

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'test/', views.test),
    url(r'test123/', views.test123),
]

结尾正斜杠/的匹配流程
当访问 http://127.0.0.1:8000/test123 时,其结尾没有正斜杠,不满足任何url函数的正则匹配条件。
django会自动在url后面添加正斜杠,并让浏览器重定向到新url: http://127.0.0.1:8000/test123/,django重新进行匹配,最后找到 url(r’test123/’, views.test123)。
3 Django 创建表关系 请求声明周期流程图 路由层
可以让django取消为url自动添加正斜杠功能。

settings.py

APPEND_SLASH = False

3.3 严格限制

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^test/$', views.test),
    url(r'^test123/$', views.test123),
]

主页匹配

urlpatterns = [
	url(r'^admin/', admin.site.urls),
	url(r'^$', views.home),
]

3.4 无名分组 有名分组

分组,就是将某一段正则表达式用小括号包起来。

3.4.1 无名分组

无名分组,就是将括号内正则表达式匹配到的内容当作位置参数传递给后面的视图函数。

urls.py

url(r'^test/(\d+)/', views.test)

访问 http://127.0.0.1:8000/test/123456/ 时,会将匹配到的内容123456传递给后面的视图函数。

views.py

def test(request, arg1):
    print(arg1)  # 123456
    return HttpResponse('test')
3.4.2 有名分组

可以给正则表达式起一个别名。
有名分组,就是将括号内正则表达式匹配到的内容当作关键字参数传递给后面的视图函数。

urls.py

url(r'^testadd/(?P<year>\d+)', views.test)

访问 http://127.0.0.1:8000/test/2020/

views.py

def test(request, year):
    print(arg1)  # 2020
    return HttpResponse('test')
3.4.3 总结
  1. 无名分组和有名分组不可以混合使用;
  2. 同一种分组可以使用多次。

urls.py

url(r'^index1/(\d+)/(\d+)/(\d+)/', views.index1),
url(r'^index2/(?P<year>\d+)/(?P<month>\d+)/(?P<date>\d+)/', views.index2),

views.py

def index1(request, *args, **kwargs):
    return HttpResponse('index1')

def index2(request, *args, **kwargs):
    return HttpResponse('index2')

3.5 反向解析

通过一些方法得到一个结果,该结果可以直接访问对应的url去触发视图函数。

  1. 先给路由与视图函数的关系起一个别名

urls.py

url(r'^func_kkk/', views.func, name='ooo')
  1. 反向解析

后端反向解析

views.py

from django.shortcuts import reverse

reverse('ooo')

前端反向解析

<a href="{% url 'ooo' %}">111</a>
相关标签: django学习 django