一、需求
現(xiàn)在我們有這樣一個需求~我們的商城里有很多的商品揭蜒,節(jié)日要來了横浑,我們要搞活動。那么我們就要設(shè)計優(yōu)惠券屉更,優(yōu)惠券都有什么類型呢伪嫁,滿減的、折扣的偶垮、立減的。
我們對應(yīng)著我們活動類型,對我們的某類商品設(shè)計優(yōu)惠券似舵,比如:家電是一類商品脚猾、食物是一類商品。那么我們可以設(shè)計家電折扣優(yōu)惠券砚哗,以及食物滿減優(yōu)惠券等......
那么我們看表結(jié)構(gòu)怎么設(shè)計???
models.py
from django.db import models
class Appliance(models.Model):
"""
家用電器表
id name
1 冰箱
2 電視
3 洗衣機(jī)
"""
name = models.CharField(max_length=64)
class Food(models.Model):
"""
食物表
id name
1 面包
2 牛奶
"""
name = models.CharField(max_length=32)
class Fruit(models.Model):
"""
水果表
id name
1 蘋果
2 香蕉
"""
name = models.CharField(max_length=32)
class Coupon(models.Model):
"""
優(yōu)惠券表
id name appliance_id food_id fruit_id
1 通用優(yōu)惠券 null null null
2 冰箱折扣券 1 null null
3 電視折扣券 2 null null
4 蘋果滿減卷 null null 1
我每增加一張表就要多增加一個字段
"""
name = models.CharField(max_length=32)
appliance = models.ForeignKey(to="Appliance", null=True, blank=True)
food = models.ForeignKey(to="Food", null=True, blank=True)
fruit = models.ForeignKey(to="Fruit", null=True, blank=True)
實(shí)際上我們商品的種類會特別的多龙助,導(dǎo)致我們這張表外鍵越來越多
遇到像Coupon這種一張表要跟多張表進(jìn)行外鍵關(guān)聯(lián)的時候~我們Django提供了ContentType組件
2、了解ContentType組件
- ContentType是Django的內(nèi)置的一個應(yīng)用蛛芥,可以追蹤項目中所有的APP和model的對應(yīng)關(guān)系提鸟,并記錄在ContentType表中。
- 當(dāng)我們的項目做數(shù)據(jù)遷移后仅淑,會有很多django自帶的表称勋,其中就有django_content_type表
ContentType組件應(yīng)用:
- 在model中定義ForeignKey字段,并關(guān)聯(lián)到ContentType表涯竟,通常這個字段命名為content-type
- 在model中定義PositiveIntergerField字段, 用來存儲關(guān)聯(lián)表中的主鍵赡鲜,通常我們用object_id
- 在model中定義GenericForeignKey字段,傳入上面兩個字段的名字
- 方便反向查詢可以定義GenericRelation字段
models.py
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
class Appliance(models.Model):
"""
家用電器表
id name
1 冰箱
2 電視
3 洗衣機(jī)
"""
name = models.CharField(max_length=64)
coupons = GenericRelation(to="Coupon")
def __str__(self):
return self.name
class Food(models.Model):
"""
食物表
id name
1 面包
2 牛奶
"""
name = models.CharField(max_length=32)
def __str__(self):
return self.name
class Fruit(models.Model):
"""
水果表
id name
1 蘋果
2 香蕉
"""
name = models.CharField(max_length=32)
def __str__(self):
return self.name
class Coupon(models.Model):
"""
優(yōu)惠券表
id name appliance_id food_id fruit_id
1 通用優(yōu)惠券 null null null
2 冰箱折扣券 1 null null
3 電視折扣券 2 null null
4 蘋果滿減卷 null null 1
我每增加一張表就要多增加一個字段
"""
name = models.CharField(max_length=32)
# 第一步
content_type = models.ForeignKey(to=ContentType)
# 第二步
object_id = models.PositiveIntegerField()
# 第三步
content_object = GenericForeignKey('content_type', 'object_id')
def __str__(self):
return self.name
view.py
from django.shortcuts import render, HttpResponse
from django import views
from app01 import models
class Text(views.View):
def get(self, request):
# 通過ContentType獲得表名
content = models.ContentType.objects.filter(app_label="app01", model="appliance").first()
# 獲得表model對象 相當(dāng)于models.Applicance
model_class = content.model_class()
obj_list = model_class.objects.all()
# 創(chuàng)建:給電器的冰箱添加優(yōu)惠券
# 第一步庐船,將想要添加優(yōu)惠券的對象取出
obj = models.Appliance.objects.filter(pk=2).first()
# 第二步银酬,創(chuàng)建優(yōu)惠券,傳入兩個參數(shù)name="冰箱優(yōu)惠券", content_object=obj
models.Coupon.objects.create(name="冰箱優(yōu)惠券", content_object=obj)
# 正向查詢:查詢優(yōu)惠券id=1綁定了哪個商品
Coupon_obj = models.Coupon.objects.filter(pk=1).first()
goods_obj = Coupon_obj.content_object
print(goods_obj)
# 反向查詢之定義了coupons = GenericRelation(to="Coupon")
appliance_obj = models.Appliance.objects.filter(pk=2).first()
results = appliance_obj.coupons.all()
print(results)
# 反向查詢之沒有定義coupons = GenericRelation(to="Coupon")
result = models.Coupon.objects.filter(content_type=content, object_id=2)
print(result)
return HttpResponse("ok")