content_type表將app名稱與其中的表的關系進行保存
通過下邊的示例來理解content_type的具體應用:
models:
from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey,GenericRelation # Create your models here. class Food(models.Model): name = models.CharField(max_length=32) coupon = GenericRelation("Coupon") class Cloth(models.Model): name = models.CharField(max_length=32) coupon = GenericRelation("Coupon") class Coupon(models.Model): """ id food_id cloth_id …… 1 null null 2 1 null """ name = models.CharField("活動名稱",max_length=64) brief = models.TextField(blank=True,null=True,verbose_name="優惠券介紹") content_type = models.ForeignKey(ContentType,blank=True,null=True) # 代表哪個app下的哪張表 object_id = models.PositiveIntegerField("綁定商品",blank=True,null=True) # 代表哪張表中的對象id content_obj = GenericForeignKey("content_type","object_id") #不會生成額外的列
view:
from django.shortcuts import render,HttpResponse from . import models def test(request): # c = models.Cloth.objects.get(id=1) # models.Coupon.objects.create(name='優惠券',brief='100減10',content_obj=c) # c = models.Cloth.objects.get(id=1) # models.Coupon.objects.create(name='優惠券',brief='200減30',content_obj=c) # 查看優惠券綁定的所有課程 # c = models.Coupon.objects.get(id=1) # print(c.content_obj) # 查看該商品下的所有優惠券 c = models.Cloth.objects.get(id=1) print(c.coupon.all()) c2 = models.Cloth.objects.values('name','coupon__brief') print(c2) return HttpResponse('ok')
總結:
當一張表作為多個表的FK,並且只能選擇其中一個或者幾個時,就可以使用content_type表;例如上面的優惠券表,被食物和衣服當作FK,數據庫表一旦建立就難以更改,如果以后需要增加電器等表並把優惠券表作為FK表,這時就不能做到在優惠券表增加列字段electr_id,因為表只能增加行記錄而不能增加列字段,因此就可以使用content_type表來將表與表中的對象進行關聯,從而做到不增加列字段的情況下增加FK關系。
在使用content_type表時,需要在FK表中增加content_type作為FK字段,並增加GenericForeignKey便於優惠券表記錄的建立以及單個優惠券對象對應的其他商品的查找。在優惠券表關聯的“一”的關系表中增加GenericRelation字段便於查找關聯的優惠券記錄的查找