简体   繁体   English

Django:如何根据查找表的值连接表

[英]Django: How to join tables based on a lookup tables' value

I am trying to do what one might consider an advanced sql query and would like to know if its possible in Django without resorting to raw sql (I will if its necessary).我正在尝试做一些可能会考虑高级 sql 查询的操作,并想知道它是否可以在 Django 中使用,而无需求助于原始 sql(如果有必要,我会这样做)。

I want to join 1 or another table based on a value located in a table lookup table and would like to do this entirely in python/django.我想根据位于表查找表中的值连接 1 或另一个表,并希望完全在 python/django 中执行此操作。

The following are rough examples of the models I am using:以下是我使用的模型的粗略示例:

class SpecificProduct(models.Model):
    specific_product_id = models.AutoField(primary_key=True)
    a_field = models.TextField()
    something_specific_to_this_model = models.CharField()


class GeneralProduct(models.Model):
    other_product_id = models.AutoField(primary_key=True)
    text = models.TextField()

TABLE_CATEGORIES = {
    1 : SpecificProduct,
    2 : GeneralProduct,
}

class ProductCategory(models.Model):
    category_id = models.AutoField(primary_key=True)
    table_category = models.IntegerField()  # Technically represents a table.
    category_text = models.CharField(max_length=20)


class Inventory(models.Model):
    inventory_id = models.AutoField(primary_key=True)
    product_category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE)
    product_pk = models.IntegerField()  # Technically foreign key to a product table.
    quantity = models.IntegerField()

What I want is a method like:我想要的是一种方法,例如:

def get_product(category_id, product_pk):
    # SQL query  magic
    return one_object_of_a_specific_product_type

This method should be able to do things like...这种方法应该能够做这样的事情......

  • Give me the product (model) where the product_category = 1 and the product_pk = 1 .给我产品(模型),其中product_category = 1product_pk = 1 (returns a SpecificProduct model) (返回一个特定产品模型)
  • Give me the product where product_category = 2 and the product_pk = 50 (returns a GeneralProduct model)给我一个product_category = 2product_pk = 50 (返回一个 GeneralProduct 模型)

How do you do this query in Django and is this even possible?您如何在 Django 中执行此查询,这甚至可能吗?

Edit: Based on Kireeti K's response I have created models that look like the following:编辑:根据 Kireeti K 的回应,我创建了如下所示的模型:

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


class SpecificProduct(models.Model):
    specific_product_id = models.AutoField(primary_key=True)
    specific_text = models.TextField()

class GeneralProduct(models.Model):
    general_product_id = models.AutoField(primary_key=True)
    text = models.TextField()

class ProductCategoryLookup(models.Model):
    category_id = models.ForeignKey(ContentType, on_delete=models.CASCADE, primary_key=True)
    category_text = models.CharField(max_length=20)


class Inventory(models.Model):
    inventory_id = models.AutoField(primary_key=True)
    product_category = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    product_id = models.PositiveIntegerField()
    product = GenericForeignKey('product_category', 'product_id')
    quantity = models.IntegerField()


def get_product(category_id, product_pk):
    content_type = ContentType.objects.get(id=category_id)
    inventory = Inventory.objects.get(product_category=content_type, product_id=product_pk).first()
    return inventory.product

You can use a generic-foreign-key to get foreign-key relation with any model sort of dynamically, read about it here.您可以使用通用外键来动态获取与任何模型类型的外键关系,请在此处阅读。 https://docs.djangoproject.com/en/2.1/ref/contrib/contenttypes/#generic-relations https://docs.djangoproject.com/en/2.1/ref/contrib/contenttypes/#generic-relations

If you rewrite your models using generic-foreign-key then it looks something like this.如果您使用 generic-foreign-key 重写模型,则它看起来像这样。

class ProductCategory(models.Model):
    category_id = models.AutoField(primary_key=True)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    table_category = models. GenericForeignKey()  # Technically represents a table.
    category_text = models.CharField(max_length=20)


class Inventory(models.Model):
    inventory_id = models.AutoField(primary_key=True)
    product_category = models.ForeignKey(ProductCategory, 
                       on_delete=models.CASCADE)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    product = models. GenericForeignKey()  # Technically foreign key to a product table.
    quantity = models.IntegerField()

Now to achieve what you want, you can implement your function like this.现在要实现您想要的功能,您可以像这样实现您的功能。

def get_product(model=None, category_id, product_pk):
    model = "specificproduct" if model else "generalproduct"
    content_type = ContentType.objects.get(model=model)
    inventory = Inventory.objects.get(product_category_id=category_id, object_id=product_pk, content_type=content_type)

    return inventory.product

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM