Django Фильтр запросов по отношениям "многие ко многим
class servers(models.Model):
hostname=models.CharField(max_length=100)
ip= models.CharField(max_length=100)
os= models.CharField(max_length=100)
class application(models.Model)
name=models.CharField(max_length=100)
URL= models.CharField(max_length=100)
servers= models.ManyToManyField(servers, blank = True, null=True)
текущее состояние БД
3 сервера 2 с ОС linux и 1 с ОС windows
2 приложения
Требование: приложение может иметь много серверов и каждый сервер может быть частью многих приложений. Нужна поддержка для создания фильтра только тех приложений, чьей операционной системой является windows. Я попробовал ниже, но он возвращает все три сервера.
def viewapp(request,pk)
criterion1 = Q(id=pk)
criterion2 = Q(servers__os__startswith="windows")
prodlist = application.objects.filter(criterion1 & criterion2)
Вы можете фильтровать поле "многие ко многим" также с помощью объекта Prefetch
[Django-doc]:
from django.db.models import Prefetch
def viewapp(request,pk):
prodlist = application.objects.filter(
id=pk, servers__os__startswith='windows'
).prefetch_related(
Prefetch('servers', Server.objects.filter(os__startswith='windows'))
)
поскольку вы здесь работаете с одним объектом, однако, лучше работать с:
from django.shortcuts import get_object_or_404
from django.db.models import Prefetch
def viewapp(request, pk):
prod = get_object_or_404(
application.objects.prefetch_related(
Prefetch('servers', Server.objects.filter(os__startswith='windows')
),
pk=pk
)
Здесь prod
есть один application
объект, а не QuerySet
из application
s.