【问题标题】:Django: Select matching foreign keys during filterDjango:在过滤期间选择匹配的外键
【发布时间】:2020-01-28 00:59:51
【问题描述】:

我们有以下示例模型,并且想知道是否可以选择在同一查询期间匹配的外键,可能作为注释。

class BaseProduct(models.Model):
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=255)
    sub_title = models.CharField(max_length=255, blank=True, null=True)
    identifier_retailer = models.CharField(max_length=255)
    tags = models.CharField(max_length=255, blank=True, null=True)
    has_multiple_variants = models.BooleanField(default=False)

class BaseProductVariant(models.Model):
    product = models.ForeignKey(BaseProduct)
    name = models.CharField(max_length=128, blank=True, null=True)
    sub_title = models.CharField(max_length=255, blank=True, null=True)
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)
    description = models.TextField(blank=True, null=True, help_text='Product description')
    features = models.TextField(blank=True, null=True, help_text='One feature per line')
    content = RedactorField(allow_image_upload=True, allow_file_upload=True, blank=True, null=True, help_text='Use this for rich HTML on featured products')
    warranty_string = models.CharField(max_length=255, blank=True, null=True)
    identifier_retailer = models.CharField(max_length=255, blank=True, null=True)
    identifier_upc = models.CharField(max_length=255, blank=True, null=True)
    identifier_model = models.CharField(max_length=255, blank=True, null=True)

我们用BaseProduct.objects.filter()...可以很方便地查询结果,但是想同时选择匹配的BaseProductVariant的列表,否则我们必须以非常规的方式查询数据库,并在prefetch_related上加入python 987654325@, select_related 也可以解决这个问题,但由于每行都需要额外的反序列化,所以速度有点慢。

【问题讨论】:

  • “匹配的外键”是什么意思?直接做BaseProduct.objects.filter().prefetch_related(baseproductvariant)有什么问题?
  • 所以任何人也看到了这个,你可以从 Django 1.7 开始执行 Prefetch(预取)。看到这个答案:stackoverflow.com/a/44845453/568508

标签: django django-queryset


【解决方案1】:

您可以使用BaseProduct 中的prefetch_related 来预取具有相关名称的变体。您还可以使用来自django.db.modelsPrefetch[1] 对象来控制预取变体结束的属性名称:

from django.db.models import Prefetch

products_with_variants = BaseProduct.objects.all().prefetch_related(
    Prefetch('baseproductvariant_set', to_attr='variants'))

for p in products_with_variants:
    print(p.variants)

[1]https://docs.djangoproject.com/en/2.2/ref/models/querysets/#django.db.models.Prefetch

【讨论】:

    猜你喜欢
    • 2018-12-13
    • 1970-01-01
    • 2020-09-07
    • 2011-03-14
    • 2021-04-17
    • 2020-09-07
    • 2012-01-23
    • 1970-01-01
    • 2016-09-19
    相关资源
    最近更新 更多