The contentType table that comes with Django for Django learning

Keywords: Python Django Database

Using django's contentType table, you can find a simple process where there are multiple foreign keys in a table: From: https://blog.csdn.net/aaronthon/article/details/81714496

contenttypes is an application built into Django that tracks the corresponding relationships between all apps and model s in a project and records them in the ContentType table.

Once the table structure of the models.py file is written, a django_content_type table is automatically generated in the database after data is migrated through the makemigrations and migrate commands, such as the tables we wrote in models.py:

from django.db import models

class Electrics(models.Model):
    """
    id    name
     1   Hitachi refrigerator
     2   Samsung TV
     3   Swan washer
    """
    name = models.CharField(max_length=32)


class Foods(models.Model):
    """
    id   name
    1    Bread
    2    Roasted Duck
    """
    name = models.CharField(max_length=32)


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


class Coupon(models.Model):  # Special Relations Table
""" 
  id    name    electric_id   food_id   cloth_id   more...   # Each additional table adds an additional field to the structure of the relationship table.
    1   General coupon   null       null      null 
    2   Refrigerator full voucher reduction   2         null     null 
    3   Bread Carnival   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)

    

      

    

    

If it is a generic coupon, then all ForeignKeys are null, if only certain goods, then the corresponding goods ForeignKey records the id of the goods, and the unrelated records are null.But there's a problem with this: there are so many categories of goods in practice, and it's likely that they will continue to increase. There will be more and more foreign keys in the coupon table, but only one or more of them will be used for each record.

contenttypes applications

This is a good solution by using the special field GenericForeignKey provided in the contenttypes application.Just take the following three steps:

Define the ForeignKey field in the model and associate it with the ContentType table.Usually this field is named "content_type"

Define the PositiveIntegerField field in the model to store the primary key in the associated table.Usually this field is named "object_id"

Define the GenericForeignKey field in the model and pass in the names of the two fields above.

To make it easier to query the coupons for a commodity, we can also define the reverse relationship in the commodity class through the GenericRelation field.

Sample code: models.py file:

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')  # For reverse queries, no table fields are generated

    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
              //Mei Man Minus Coupon 9 (electrics) 3
              //Pig's feet get one free coupon 10*2
              //Antarctic quilt 200 minus 50 coupons 11 1
    """
    name = models.CharField(max_length=32)

    content_type = models.ForeignKey(to=ContentType,on_delete=models.CASCADE) # Since step 1 does not have a direct foreign key relationship with the associated table, we first find the related table by taking this step
    object_id = models.PositiveIntegerField() # step 2  #The id of the corresponding record of the associated table is stored
    content_object = GenericForeignKey('content_type', 'object_id') # The step 3 object.content_object gets the merchandise record object associated with this coupon object directly.

    def __str__(self):
        return self.name

Note: ContentType only works with 1-to-many relationships!!!And that many tables have multiple ForeignKey fields.

Data migration, adding data to each table

Clothes, electrical, bedding, food tables

After adding, data migration, Python management.py makemigrations and python management.py migrate

Create records and queries

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


def test(request):
    if request.method == 'GET':
        # The ContentType table object has the model_class() method and gets the corresponding model
        content = ContentType.objects.filter(app_label='api', model='electrics').first()  # Table name lowercase
        cloth_class = content.model_class() # cloth_class is equivalent to models.Electrics
        res = cloth_class.objects.all()
        print(res)

        # Create a discount record for Samsung TV (id=2)
        s_tv = models.Electrics.objects.filter(id=2).first()
        models.Coupon.objects.create(name='TV coupons', content_object=s_tv)

        # Query which item the coupon (id=1) is bound to
        coupon_obj = models.Coupon.objects.filter(id=1).first()
        prod = coupon_obj.content_object
        print(prod)

        # Query all coupons for Samsung TV (id=2)
        res = s_tv.coupons.all()
        print(res)

  

Summary: When a table is associated with multiple tables FK and only one or n of the multiple FKs can be selected, contenttypes app can be used to define only three fields.

Create Records

The structure of the relationship table

    

Use grammar to record relationships.

Add mode 1:

    

    

    

Next use postmen s to send requests

    

The voucher table data is then added

    

Add mode 2:

    

Send request results through postmen s

    

- Query records

Query voucher information for name="E-commerce 1 voucher"

    

    

Posted by microbluechip on Thu, 12 Dec 2019 18:19:11 -0800