首页 > 其他 > 详细

Django之ContentType

时间:2020-03-25 14:55:02      阅读:54      评论:0      收藏:0      [点我收藏+]

一: ContentType

  contenttype是Django内置应用, 表明项目中app和model的队形关系, 记录下来.

  models.py文件中的表结构创建好后, 通过数据迁移命令, 会自动在数据库中生成django_content_type表

二: contenttype所在位置及表中结构

技术分享图片

  

说明: 在models.py创建一个表并执行数据迁移命令, contenttype中就会出现该应用对应的类

三: contenttype的用处

  用在多个表关联一个表, 并且是一对多的对应关系

  比如我们商品的各种优惠券: 就是多个商品表对应一个优惠券表(我们通过通过外键把商品表和优惠券表进行关联)

from django.db import models


class Electrics(models.Model):
    """
    id    name
  日立冰箱
  三星电视
  小天鹅洗衣机
    """
    name = models.CharField(max_length=32)


class Foods(models.Model):
    """
    id   name
   面包
   烤鸭
    """
    name = models.CharField(max_length=32)


class Clothes(models.Model):
    name = models.CharField(max_length=32)


class Coupon(models.Model):  # 特殊关系表
""" 
  id    name    electric_id   food_id   cloth_id   more...   # 每增加一张表,关系表的结构就要多加一个字段。
   1   通用优惠券   null       null      null 
   2   冰箱满减券   2         null     null 
   3   面包狂欢节   null        1      null 
""" 
name = models.CharField(max_length=32) 
electric = models.ForeignKey(to=Electrics, null=True) 
food = models.ForeignKey(to=Foods, null=True) 
cloth = models.ForeignKey(to=Clothes, null=True)

 通用的优惠券, 关联可以为null, 如果是某个商品的优惠券, 优惠券表中就要记录该优惠券所对应的商品表的id.

 那么要是在添加其他商品的优惠券, 一直在后面加,  表会越来越长, 其余的地方为空, 不好. 就需要用contenttype表进行处理

四: contenttype的用法

  1. 在model中定义ForeignKey字段, 并关联到ContentType表, 通常该字段命名为"content_type"

  2. 在model中定义PositiveIntegerField字段, 用来存储关联表中的键, 通常该字段命名为"object_id"

  3. 在model中定义GenericForeignKey字段, 传入上面两个字段

  在商品表中通过GenericRelation字段定义反向关联

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


class Electrics(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField(default=100)
    coupons = GenericRelation(to=Coupon)  # 用于反向查询,不会生成表字段

    def __str__(self):
        return self.name


class Foods(models.Model):
    name = models.CharField(max_length=32)
    price=models.IntegerField(default=100)
    coupons = GenericRelation(to=Coupon)

    def __str__(self):
        return self.name


class Clothes(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField(default=100)
    coupons = GenericRelation(to=Coupon)

    def __str__(self):
        return self.name


class bed(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField(default=100)
    coupons = GenericRelation(to=Coupon)


class Coupon(models.Model):
    """
    Coupon
        id    name                      content_type_id       object_id_id
        1   美的满减优惠券            9(电器表electrics)  3
       2   猪蹄买一送一优惠券        10                    2
       3   南极被子买200减50优惠券   11                    1
    """
    name = models.CharField(max_length=32)

    content_type = models.ForeignKey(to=ContentType) # step 1
    object_id = models.PositiveIntegerField() # step 2
    content_object = GenericForeignKey(content_type, object_id) # step 3

    def __str__(self):
        return self.name

 

contenttype表情况

技术分享图片

 

views.py(查询和创建)

from django.shortcuts import render, HttpResponse
from api import models
from django.contrib.contenttypes.models import ContentType


def test(request):
    if request.method == GET:
        # ContentType表对象有model_class() 方法,取到对应model
        content = ContentType.objects.filter(app_label=api, model=electrics).first()  # 表名小写
        cloth_class = content.model_class() # cloth_class 就相当于models.Electrics
        res = cloth_class.objects.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=api, model=model_name).first()
        res = models.OftenAskedQuestion.objects.filter(content_type=content, object_id=obj.pk).all()

        return HttpResponse(....)

 

原文链接参考: https://www.cnblogs.com/aaronthon/p/9286459.html

Django之ContentType

原文:https://www.cnblogs.com/zhuangshenhao/p/12142256.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!