day96-跨域请求&ContenType处理多表外键关系

2020-03-24 15:08:02 浏览数 (1)

1.解决跨域请求

1.1跨域仅存在于测试环境当中,新建一个中间件,代码如下

代码语言:javascript复制
from django.utils.deprecation import MiddlewareMixin


class MyCors(MiddlewareMixin):
    @staticmethod
    def process_response(request, response):
        response["Access-Control-Allow-Origin"] = "*"
        if request.method == "OPTIONS":
            # 信息头
            response["Access-Control-Allow-Headers"] = "Content-Type, AUTHENTICATE"
            # 请求方式
            response["Access-Control-Allow-Methods"] = "PUT, PATCH, DELETE"
        return response

1.2在settings里面注册这个中间件

1.3在认证类里面添加

2.Django自带的ContenType处理一张表对多表外键关系

2.1ContentType表会将models里面所有的表全部录入进来,也包括自带的所有的表

2.2models表,注意第一版的设计,如果外键特多,就知道为什么使用ContentType了

2.2.1 GenericForeignKey 不生成字段,用于处理外键关联对象

2.2.2 GenericRelation 不生成字段,只用于反向查询

2.2.3 注意外键指向 ContentType 这张表

2.2.4 GenericForeignKey 接受两个参数,指向 ContentType 的表字段和单条 model 对象,使用体现在2.4.2

代码语言:javascript复制
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models


# Create your models here.

class Food(models.Model):
    """
    id    name
    1     蛋炒饭
    2     山东煎饼
    3     茶叶蛋
    """
    name = models.CharField(max_length=32)
    # 不生成字段只用于反向查询
    coupons = GenericRelation(to="Coupon")


class Fruit(models.Model):
    """
    id    name
    1     黄心西瓜
    2     奇异果
    3     猕猴桃
    """
    name = models.CharField(max_length=32)
    # 不生成字段只用于反向查询
    coupons = GenericRelation(to="Coupon")


class Coupon(models.Model):
    """
    id    title            table_id   object_id
    1     蛋炒饭半价           1            1
    2     黄心西瓜五折         2            1
    3     茶叶蛋一块钱三个      2            3
    4     奇异果六折           2            2
    """
    # 第一版设计,外键太多会崩溃的,尤其是商城
    # food = models.ForeignKey(to="Food")
    # fruit = models.ForeignKey(to="Fruit")
    
    title = models.CharField(max_length=32)
    # ContentType作为Django自带的表,会注册所有的视图表进入数据库表
    # 表的 id 外键是 ContentType表
    table= models.ForeignKey(to=ContentType)
    object_id = models.IntegerField()
    # 不会生成字段,仅仅用于关联对象
    content_object = GenericForeignKey('table', 'object_id')

2.3生成的coupon表

2.4视图里面的使用

2.4.1 第一版是普通的传参方式,按照 title,object_id,content_type 三个参数传参

2.4.2 第二版就体现了 content_object 的作用,接收一个对象,内部帮你创建 object_id 和 content_type_id

代码语言:javascript复制
class TestView(APIView):
    def get(self, request):
        # 第一版
        # 给 food 创建优惠券
        # 直接传参
        dic = {"food_id": 2, 'coupon': '煎饼五折'}
        models.Coupon.objects.create(
            title=dic['coupon'],
            content_type_id=ContentType.objects.filter(model='food').first().id,
            object_id=dic["food_id"]
        )

        """"""
        # 第二版,使用 content_object 传一个对象
        # dic = {"fruit_id": 1, 'coupon': '黄心西瓜五折'}
        # 首先查询出这个对象
        # fruit_obj = models.Fruit.objects.filter(id=dic["fruit_id"]).first()
        # 直接传一个对象,content_object会直接帮助我们找到表id并创建
        # content_type 和 object_id
        # models.Coupon.objects.create(title=dic['coupon'], content_object=fruit_obj)
        """"""
        # 根据 Coupon 表的不生成资源的 content_object 直接获得关联对象
        obj = models.Coupon.objects.filter(id=4).first()
        print(obj.content_object)
        return HttpResponse('ok')

        return HttpResponse('ok')

0 人点赞