day96-Cross-domain request & ContenType handles multi-table foreign key relationships

day96-Cross-domain request & ContenType handles multi-table foreign key relationships

1. Resolve cross-domain requests

1.1 Cross-domain only exists in the test environment, create a new middleware, the code is as follows

from django.utils.deprecation import MiddlewareMixin


class MyCors(MiddlewareMixin):
    @staticmethod
    def process_response(request, response):
        response["Access-Control-Allow-Origin"] = "*"
        if request.method == "OPTIONS":
            # Information header
            response["Access-Control-Allow-Headers"] = "Content-Type, AUTHENTICATE"
            # Request method
            response["Access-Control-Allow-Methods"] = "PUT, PATCH, DELETE"
        return response

1.2 Register this middleware in settings

1.3 Add in the authentication class

2. Django's own ContenType handles a table-to-multi-table foreign key relationship

2.1 The ContentType table will enter all the tables in the models, including all the tables that come with it

2.2models table, pay attention to the design of the first edition, if there are too many foreign keys, you will know why ContentType is used

2.2.1 GenericForeignKey does not generate fields and is used to process foreign key related objects

2.2.2 GenericRelation does not generate fields and is only used for reverse query

2.2.3 Note that the foreign key points to the ContentType table

2.2.4 GenericForeignKey accepts two parameters, which point to the table field of ContentType and a single model object. The use is reflected in 2.4.2

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 egg fried rice
    2 Shandong pancakes
    3 tea eggs
    """
    name = models.CharField(max_length=32)
    # Do not generate fields only for reverse query
    coupons = GenericRelation(to="Coupon")


class Fruit(models.Model):
    """
    id name
    1 yellow heart watermelon
    2 Kiwi
    3 kiwi
    """
    name = models.CharField(max_length=32)
    # Do not generate fields only for reverse query
    coupons = GenericRelation(to="Coupon")


class Coupon(models.Model):
    """
    id title table_id object_id
    1 Half price of egg fried rice 1 1
    2 50% off yellow heart watermelon 2 1
    3 3.tea eggs for one dollar 2 3
    4 40% off kiwi 2 2
    """
    # The first version of the design, too many foreign keys will crash, especially the mall
    # food = models.ForeignKey(to="Food")
    # fruit = models.ForeignKey(to="Fruit")
    
    title = models.CharField(max_length=32)
    # ContentType, as Django's own table, will register all view tables into the database table
    # The id foreign key of the table is the ContentType table
    table = models.ForeignKey(to=ContentType)
    object_id = models.IntegerField()
    # No fields will be generated, only used for associated objects
    content_object = GenericForeignKey('table','object_id')

2.3 The generated coupon table

2.4 Use in the view

2.4.1 The first version is a common way of passing parameters, according to the title, object_id, content_type three parameters to pass parameters

2.4.2 The second edition embodies the role of content_object, receives an object, and creates object_id and content_type_id internally for you

class TestView(APIView):
    def get(self, request):
        # First edition
        # Create a coupon for food
        # Direct transfer of parameters
        dic = {"food_id": 2,'coupon': '50% off pancakes'}
        models.Coupon.objects.create(
            title=dic['coupon'],
            content_type_id=ContentType.objects.filter(model='food').first().id,
            object_id=dic["food_id"]
        )

        """"""
        # 2.edition, use content_object to pass an object
        # dic = {"fruit_id": 1,'coupon':'Yellow heart watermelon 50% off'}
        # First look up this object
        # fruit_obj = models.Fruit.objects.filter(id=dic["fruit_id"]).first()
        # Pass an object directly, content_object will directly help us find the table id and create it
        # content_type and object_id
        # models.Coupon.objects.create(title=dic['coupon'], content_object=fruit_obj)
        """"""
        # Obtain the associated object directly according to the content_object of the Coupon table that does not generate resources
        obj = models.Coupon.objects.filter(id=4).first()
        print(obj.content_object)
        return HttpResponse('ok')

        return HttpResponse('ok')
Reference: https://cloud.tencent.com/developer/article/1598531 day96-Cross-domain requests & ContenType handling multi-table foreign key relationships-Cloud + Community-Tencent Cloud