我正在尝试做一个可能被认为是高级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 = 1
和
product_pk = 1
。 (返回特定产品模型)product_category = 2
和product_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
答案 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