Эквивалентность фильтра набора запросов Django SQL

#django #django-queryset #django-database

#django #django-queryset #django-база данных

Вопрос:

Для меня неясно или отсутствует пример кода для понимания документации о том, как язык SQL внутренне используется в Django ORM.

Мой предполагаемый SQL:

 SELECT projects_category.id, projects_category.name, projects_project.name
FROM projects_category
    JOIN projects_project_categories
        ON projects_category.id = projects_project_categories.project_id
    JOIN projects_project
        ON projects_project_categories.project_id=projects_project.id
            WHERE NOT projects_project.is_mini ORDER BY projects_category.id;
  

Как сделать то же самое в Django ORM или в Django view?
Я пробовал фильтровать и исключать (возможно, с неправильными аргументами …), и, похоже, он не работает в соответствии с выводом. Помимо этих двух вариантов могут быть и другие.

Кроме того, любой другой трюк был бы заметен.

Мои соответствующие модели ниже:

 class Project(models.Model):
    name = models.CharField(max_length=100)
    is_mini = models.BooleanField(default=False)
    categories = models.ManyToManyField('Category', blank=True)

    def __str__(self):
        return self.name

class Category(models.Model): # will be used for search
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name
  

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

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

1. Можете ли вы предоставить свои модели django, которые относятся к этому?

Ответ №1:

Чтобы выполнить этот запрос, я предлагаю сделать это следующим образом:

 Project.objects.values('name','categories__name','categories__id').filter(is_mini=False).order_by('id')
  

.values позволяет вам выбирать столбцы, которые вы хотите выбрать из объекта Project. И поскольку он имеет множество связей с «категорией», вы можете получить доступ к данным этих категорий с помощью ключевого слова 'categories__field' .

Ответ №2:

Несколько примеров с разной производительностью:

Общий набор запросов

 Project.objects.filter(is_mini=False).order_by('categories__id')
  

Только необходимые значения

 Project.objects.only("name", "categories__name", "categories__id").filter(
    is_mini=False
).order_by('categories__id')  
  

Категории предварительной выборки значения

Вы можете объединить этот ответ с ответом @Midoki и использовать values вместо only или даже values_list . Документ здесь

 Project.objects.values("name", "categories__name", "categories__id").filter(
    is_mini=False
).prefetch_related("categories").order_by("categories__id")
  

Когда вы используете поле ManyToMany (и если здесь много строк), вы можете разрешить Django ORM предварительную выборку categories для повышения производительности. Документы здесь