Django: Выберите подходящие внешние ключи во время фильтра - PullRequest
0 голосов
/ 27 сентября 2019

У нас есть следующие примеры моделей, и мы задаемся вопросом, возможно ли выбрать внешние ключи, которые соответствуют во время того же запроса, возможно, в качестве аннотации.

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, в противном случае мы должны запросить базу данных нетрадиционным способом и присоединиться в pythonс prefetch_related на BaseProductVariant.objects.filter(product__in=[]).prefetch_related(product), select_related тоже работает, но немного медленнее из-за дополнительной десериализации в каждой строке.

1 Ответ

1 голос
/ 27 сентября 2019

Вы можете использовать prefetch_related из BaseProduct, чтобы предварительно выбрать варианты с соответствующим именем.Вы также можете использовать объект Prefetch [1] из django.db.models для управления именем атрибута, в котором заканчиваются предварительно выбранные варианты:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...