当前位置 : 主页 > 手机开发 > 其它 >

DRF多表设计与ModelSerializer组件

来源:互联网 收集:自由互联 发布时间:2021-06-19
一:多表设计 (1)模型表字段 """ Book表:name、price、img、authors、publish、is_delete、create_timePublish表:name、address、is_delete、create_time Author表:name、age、is_delete、create_timeAuthorDetail表:

一:多表设计

(1)模型表字段

"""
Book表:name、price、img、authors、publish、is_delete、create_time

Publish表:name、address、is_delete、create_time
    
Author表:name、age、is_delete、create_time

AuthorDetail表:mobile, author、is_delete、create_time
    
BaseModel基表
    is_delete、create_time
上面四表继承基表,可以继承两个字段
"""

PS:

  (1)表格都有是否删除字段 创建时间字段

  (2)抽象继承一个模型表(基表)

(2)基表的创建

class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    create_time = models.DateTimeField(auto_now_add=True)

    # 设置 abstract = True 来声明基表,作为基表的Model不能在数据库中形成对应的表 重点
    class Meta:
        abstract = True

(3)断关联多表关系

(1)作用:

  (1)物理上断开关系提升查找效率

  (2)防止环装表关系 导致表关系成为死表(即不能再操作表 如果想要在重新操作表格 需要删库跑路)

(2)字段设计

1:外键字段
    (1)一对多:外键存放在多的一方
    (2)一对一:从逻辑正反向考虑 如作者与作者详情 作者删除 作者详情级联更新  作者详情删除 作者还在 因此将外键存放在详情表中
    (3)多对多:在关系表中

2:ORM查询
    (1)正向查询:通过外键字段
    (2)反向查询:听过ralated_name

(3)连表操作关系
    (1)作者删除--->作者详情删除---->cascade
    (2)作者删除--->作者详情为空---->set_null
    (3)作者删除--->作者详情默认---->set-defalut
    (4)作者删除--->作者详情无损---->do_nothing
字段设计
    # 作者详情表中的
    author = models.OneToOneField(
        to=Author,
        related_name=detail,
        db_constraint=False,
        on_delete=models.CASCADE
    )
    
    # 图书表中的
    publish = models.ForeignKey(
        to=Publish,
        related_name=books,
        db_constraint=False,
        on_delete=models.DO_NOTHING,
    )
    authors = models.ManyToManyField(
        to=Author
        related_name=books,
        db_constraint=False,
    )

PS:

  (1)多对多表关系不能设置on_delete

  (2)一对一,一对多必须设置on_delete 

  (3)1.X的Django默认设置on_delete 2.X需要手工设置

(4)模型表创建

# 1) 基表
class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    create_time = models.DateTimeField(auto_now_add=True)

    # 作为基表的Model不能在数据库中形成对应的表,设置 abstract = True
    class Meta:
        abstract = True


class Book(BaseModel):
    """name、price、img、authors、publish、is_delete、create_time"""
    name = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    img = models.ImageField(upload_to=img, default=img/default.jpg)
    publish = models.ForeignKey(
        to=Publish,
        db_constraint=False,  # 断关联
        related_name=books,  # 反向查询字段:publish_obj.books 就能访问所有出版的书
        on_delete=models.DO_NOTHING,  # 设置连表操作关系
    )
    authors = models.ManyToManyField(
        to=Author,
        db_constraint=False,
        related_name=books
    )

    # 序列化插拔式属性 - 完成自定义字段名完成连表查询
    @property
    def publish_name(self):
        return self.publish.name

    @property
    def author_list(self):
        return self.authors.values(name, age, detail__mobile).all()

    class Meta:
        db_table = book
        verbose_name = 书籍
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.name

class Publish(BaseModel):
    """name、address、is_delete、create_time"""
    name = models.CharField(max_length=64)
    address = models.CharField(max_length=64)

    class Meta:
        db_table = publish
        verbose_name = 出版社
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.name

class Author(BaseModel):
    """name、age、is_delete、create_time"""
    name = models.CharField(max_length=64)
    age = models.IntegerField()

    class Meta:
        db_table = author
        verbose_name = 作者
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.name

class AuthorDetail(BaseModel):
    """mobile, author、is_delete、create_time"""
    mobile = models.CharField(max_length=11)
    author = models.OneToOneField(
        to=Author,
        db_constraint=False,
        related_name=detail,
        on_delete=models.CASCADE,
    )

    class Meta:
        db_table = author_detail
        verbose_name = 作者详情
        verbose_name_plural = verbose_name
    def __str__(self):
        return %s的详情 % self.author.name
模型表

二:ModelSerializer

(1)settings文件配置

INSTALLED_APPS = [
    # 注册rest_framework
    rest_framework,
]

DATABASES = {
    default: {
        ENGINE: django.db.backends.mysql,
        NAME: database,
        USER: root,
        PASSWORD: 123,
    }
}
"""
任何__init__文件
import pymysql
pymysql.install_as_MySQLdb()
"""

LANGUAGE_CODE = zh-hans
TIME_ZONE = Asia/Shanghai
USE_I18N = True
USE_L10N = True
USE_TZ = False

MEDIA_URL = /media/
MEDIA_ROOT = os.path.join(BASE_DIR, media)
settings文件配置

(2)主路由层配置

from django.conf.urls import url, include
from django.contrib import admin
from django.views.static import serve
from django.conf import settings
urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^api/, include(api.urls)),
    url(r^media/(?P<path>.*), serve, {document_root: settings.MEDIA_ROOT}),
]
主路由

(3)子路由层

网友评论