Django content-type used in the assembly

content-type components

ContentType is built in a Django application and all correspondence between the APP and the model can track the project, and recorded in ContentTpe table, when we do data migration project, there will be many django comes with the table, among them django_content_type table

scenes to be used

When online shopping mall, there will be a variety of coupons, such as General coupons, full cut volume, or only a specific category of coupons, the way we used to be in the database by the foreign key coupons and different categories of merchandise table associate

from django.db import models
class Electrics(models.Model):
    '''
    id  name
    1   格力空调
    2   小天鹅洗衣机
    3   好太太洗碗机
    '''
    name = models.CharField(max_length=32)
 class Foods(models.Model):
    '''
    id  name
    1   肉松小贝
    2   北京烤鸭
    3   梨膏糖
    '''
    name=models.CharField(max_length=32)
class Clothers(model.Model):
    name=models.CharField(max_lenght=32)
class Coupon(models.Model):
    '''
    id  name          Electrics         Foods       Clothes  ...
    1   通用优惠卷       null             null         null
    2   冰箱满减           2              null         null
    3    面包狂欢节       null             1            null
    '''
    name =models.CharField(max_length=32)
    electric_obj=models.ForeignKey(to='Electrics',null=True)
    food_obj=models.ForeignKey(to='Foods',null=True)
    cloth_obj=models.ForeignKey(to='Clothes',null=True)

All are associated with the Coupon to this table, if the coupon is generic, all ForeignKey corresponding field is null, if only some of the product, then the product id, irrelevant of recording record corresponding to commodity ForeignKey null

Problems

1, a wide range of goods in practice, and probably will continue to increase, then the foreign key concessions label in more and more frequent need to modify the table

2, wherein each record using only one or a few foreign key field, this will result in wasted space table

Solution
  • ForeignKey fields defined in the model, and associated with the table ContentType, generally designated as the content-type field
  • PositiveIntergerField model defined in the field, for storing the primary key in the association table, usually object_id
  • GenericForeignKey defined fields in the model, an incoming above two fields, a reverse query definition GenericRelation
from django.db import models
from django.contrib.contenttypes.models improt ContentType
from django.contrib,contenttypes.models import GenericForeignKey

class Electrics(models.Model):
    name=models.CharField(max_length=32)
    coupons=GenericRelation(to='Coupon')
    def __str__(self):
        return self.name
class Foods(models.Model):
    name=models.CharField(max_length=32)
    coupons=GenericRelation(to='Coupon')
    def __str__(self):
        return self.name
class Clothes(models.Model):
    name=models.CharField(max_length=32)
    coupons=GenericRelation(to='Coupon')
    def __str__(self):
        return self.name
class Coupon(models.Model):
    name=models.CharField(max_length=32)
    content_type=models.ForeignKey(to=ContentType)
    object_id=models.PositiveInterField()
    content_object=GenericForeignKey('content_type','object_id')
    def __str__(self):
        return self.name
from django.shortcuts import render,HttpResponse
from app01 import models
from django.contrib.contenttypes.models import ContentType

def text(request):
    if request.method=='GET':
        content=ContentType.objects.filter(app_label='app01',model='electrics').first()
        cloth_class=content.model_class()  #相当于models.Electrics
        res=cloth_class.object.all()
        print(res)
        
        ##为三星电视(id=2)创建一条优惠记录
        s_tv=models.Electrics.objects.filter(id=2).first()
        models.Coupon.objects.create(name='电视优惠卷',content_object=s_tv)
        
        ##查询优惠卷(id=1)绑定了那些商品
        coupon_obj=models.Coupon.objects.filter(id=1).first()
        prod=coupon_obj.content_object
        print(prod)
        
        ##查询三星电视(id=2)的所有优惠卷
        res=s_tv.coupons.all()
        print(res)
        
        ##查询obj的所有优惠卷:如果没有定义反向查询字段
        content=ContentType.objects.filter(app_label='app01',model='model_name').first()
        res=models.OftenAskedQuestion.objects.filter
        (content_type=content,object_id=obj.pk).all()
        return HttpResponse('pass')

to sum up

When a plurality of tables and FK association table, and wherein the plurality of FK can only select one or more where n may be utilized contenttypes app, only need to define three bullets to get, also common scenarios: a plurality of commodity kinds of coupons, a variety of courses in accordance with the cycle of price, etc.

Guess you like

Origin www.cnblogs.com/lzss/p/12168521.html