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

时间:2018-11-15 03:03:41

标签: python sql django orm

我正在尝试做一个可能被认为是高级sql查询的事情,并且想知道在Django中是否可以不使用原始sql(如果需要的话,我会这样做)。

我想基于表查找表中的值连接1个或另一个表,并希望完全在python / django中做到这一点。

以下是我正在使用的模型的粗略示例:

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()

我想要的是一种类似的方法:

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

此方法应该能够执行以下操作...

  • 请给我product_category = 1product_pk = 1。 (返回特定产品模型)
  • product_category = 2product_pk = 50的产品给我 (返回GeneralProduct模型)

您如何在Django中执行此查询,甚至有可能吗?

编辑: 根据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

1 个答案:

答案 0 :(得分:1)

您可以使用通用外键动态获取与任何模型类型的外键关系,请在此处阅读。 https://docs.djangoproject.com/en/2.1/ref/contrib/contenttypes/#generic-relations

如果您使用通用外键重写模型,则看起来像这样。

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()

现在要实现所需的功能,就可以像这样实现您的功能。

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