Предварительная выборка набора запросов при related_name=» «

#django #django-models #django-orm

#django #django-модели #django-orm

Вопрос:

Возможно ли без связанного name ( related_name=" " ) выполнять предварительную выборку объектов в целевом экземпляре? Конечно, я знаю, что это не проблема с соответствующим именем, но я не совсем уверен, возможно ли это без него.

Вот пример кода:

 from django.db import models


class Parent(models.Model):
    name = models.CharField(max_length=50)


class Child(models.Model):
    parent = models.ForeignKey(to=Parent, related_name=" ", on_delete=models.CASCADE)
    name = models.CharField(max_length=50)


Parent.objects.all().prefetch_related('child_set')
 

Может быть, это возможно с помощью Prefetch(lookup, queryset=None, to_attr=None) объекта, потому что он принимает набор запросов в списке аргументов?

Комментарии:

1. С какой проблемой вы столкнулись здесь? Вы пробовали и столкнулись с ошибкой или задаете похожий вопрос «что, если»?

2. @Charnel Проблема в том, что связанное имя используется при поиске в наборе запросов, поэтому, когда связанное имя не задано, его нельзя использовать в поиске в наборе запросов, например Parent.objects.filter(child__[insert attribute]=...) . То же самое относится и к предварительным выборкам.

3. Вы все равно можете использовать _set sufix like fieldname_set , если вы не указали связанное имя.

4. У меня related_name=" " это есть в названии вопроса и в примере кода.

5. Какой смысл related_name=" " , если вы все равно хотите получить доступ к обратной связи?

Ответ №1:

Немного просмотрел код и нашел эту строку:

 rel_obj_descriptor = getattr(instance.__class__, through_attr, None)
 

Здесь instance указан экземпляр модели, а through_attr также имя поля связанного экземпляра, который будет извлечен. Эта строка в основном пытается получить связанный дескриптор для выполнения запроса предварительной выборки. В вашем случае rel_obj_descriptor будет содержать None .
Чтобы ответить на ваш вопрос, нет, это невозможно, по крайней мере, для внешнего ключа, может быть некоторый взлом для многих отношений, поскольку Django, похоже, использует для них некоторые внутренние дескрипторы.
Я бы посоветовал вам просто не устанавливать related_name=" " , поскольку вы хотите использовать здесь обратную связь. Вы говорите «Это из-за разделения задач между несколькими приложениями», но это не имеет особого смысла. Разве мы не устанавливаем внешний ключ для модели пользователя для различных других моделей в любом случае и по-прежнему используем связанное имя? Возникает ли там точка разделения проблем (пользовательская модель находится в отдельном приложении)?

Ответ №2:

попробуйте

 parent = Parent.objects.get(id=pk)
parent.child_set.all()
 

Я не знаю, предотвращает ли наличие related_name = ‘ ‘ эту ситуацию, но если вы никогда не определяете related_name, вы определенно можете использовать этот метод.

Комментарии:

1. Да, но related_name=" " требуется.

2. вы пробовали это?? parent = Parent.objects.get(id=pk) parent.child_set.all()

3. Пожалуйста, прочитайте вопрос еще раз и обсуждение под вопросом.