Django APP之contenttypes簡單應用

 

Conttenttypes介紹

當你看到contenttype你是否是想到了請求頭的contenttype?python

可是數據庫

此contenttypes不是請求頭Content-Type而是Django自帶的appdjango

或許你當時沒有注意到contenttypes,這裏簡單的介紹一下,如何用Django自帶的contenttypes編程

 

業務需求

咱們要開設兩大門課程,一個是專業課,一個是學位課,網絡

好比專業課有:app

  •  21天python入門
  • 網絡編程
  • Linux基礎

學位課:運維

  • Python全棧開發
  • Linux運維

每個課程有不一樣的週期,不一樣的週期對應不一樣的價格.spa

好比專業課的21天python入門 週期7天10塊錢 週期14天15塊錢設計

那麼你如何設計的你表結構呢?code

 

一張學位課表,一張專業課表示必須的,那麼價格表如何設計呢?

使用一張價格表?

若是某天咱們須要添加一門面授課,那麼你須要在價格表上修改字段嗎?增長一個Fk對應面授課?

顯然不行

那麼每個課對應一張表?那我有10個課,那豈不是有10個價格表?形成了資源的浪費.

 

那麼有什麼好的方案?

xid對應着哪一門具體的課程,table_id對應着表的名字,好比第一條table_id對應Course表id爲1 21天入門python

下次須要增長課的時候,只須要增長課表,還有在存放表名的表中增長一個id對應的表名就能夠解決.

可能你會說這樣查詢起來很麻煩,NO Django已經幫你作好了.

 

Conttenttypes的應用

加入表簡單的表結構

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation


class DegreeCourse(models.Model):
    """學位課程"""
    name = models.CharField(max_length=128, unique=True)
    course_img = models.CharField(max_length=255, verbose_name="縮略圖")
    brief = models.TextField(verbose_name="學位課程簡介", )


class Course(models.Model):
    """專題課程"""
    name = models.CharField(max_length=128, unique=True)
    course_img = models.CharField(max_length=255)

    # 不會在數據庫生成列,只用於幫助你進行查詢
    policy_list = GenericRelation("PricePolicy")


class PricePolicy(models.Model):
    """價格與有課程效期表"""
    content_type = models.ForeignKey(ContentType,on_delete=models.CASCADE)  # 關聯course or degree_course
    object_id = models.PositiveIntegerField()

    #不會在數據庫生成列,只用於幫助你進行添加和查詢
    content_object = GenericForeignKey('content_type', 'object_id')

    valid_period_choices = (
        (1, '1天'),
        (3, '3天'),
        (7, '1周'), (14, '2周'),
        (30, '1個月'),
        (60, '2個月'),
        (90, '3個月'),
        (180, '6個月'), (210, '12個月'),
        (540, '18個月'), (720, '24個月'),
    )
    valid_period = models.SmallIntegerField(choices=valid_period_choices)
    price = models.FloatField()
content_object = GenericForeignKey('content_type', 'object_id')裏面的字段名必須是content_type,object_id 由於GenericForeignKey類的源碼裏已經寫清楚了

 

建立字段

那麼咱們如何添加一個價格字段?

    models.PricePolicy.objects.create(
        valid_period=14,
        price=9.9,
content_object=models.Course.objects.get(id=1) )

 content_object 字段對應的必須是一個對象,是你想要關聯的object_id的對象.只要對應了一個對象他就會自動的幫你添加

content_type 對應的存放表id
object_id 對應了課表的id

在你建立表的時候,Djnaog會自動幫你建立第三張表,就是id對應表名

 

查詢

   # 2. 根據某個價格策略對象,找到他對應的表和數據,如:關聯課程名稱
    price = models.PricePolicy.objects.get(id=2)
    print(price.content_object.name) 
    # 自動幫你找到對應課程的對象

 

若是要課程查詢全部價格須要在課程表上添加一個字段

    # 不會在數據庫生成列,只用於幫助你進行查詢
    policy_list = GenericRelation("PricePolicy")
根據這個字段名能夠跨表查詢
# 3.找到某個課程關聯的全部價格策略
    obj = models.Course.objects.get(id=1)
    for item in obj.policy_list.all():
        print(item.id,item.valid_period,item.price)

 

何時要用contenttypes?

  • 某一張表須要對應多個Fk字段的時候 且Fk所對應的表是同一種類型
  • 且一旦增長業務的時候,須要在該表增長FK字段
相關文章
相關標籤/搜索