Django Отношения ManyToMany избегают дублирования - PullRequest
1 голос
/ 05 мая 2020

Я два дня думал над этим вопросом и не могу осмыслить его. Допустим, у меня есть модель под названием «Автомобиль», которая имеет много-много взаимосвязей с моей моделью пользователя. «Профиль» означает, что в моей пользовательской модели (так называемый профиль) у меня есть:

cars = models.ManyToManyField(Cars, related_name = 'profiles')

Теперь модель автомобиля имеет много-много отношений, называемых лайками, поэтому всякий раз, когда пользователю нравится машина, она будет добавлена ​​к лайкам этой машины:

car.likes.add(user)

Теперь моя модель «Автомобиль» будет иметь 4 поля, которые являются моделью, годом , имя, цвет Проблема в том, что я хочу запросить базу данных, чтобы получить количество лайков для всех автомобилей только определенных моделей и лет. То есть независимо от имени и цвета я хочу получить количество лайков. Теперь я знаю, что могу получить лайки, если все модели с определенной моделью и годом, написав:

def get_total_likes(self):
   Car.likes.through.objects.filter(car__model=self.model, car__year=self.year).count()

Теперь представьте сценарий, в котором пользователю нравится машина с моделью = A, годом = 1, цветом = r, name = something, а затем они решают, что им нравится машина с model = A, year = 1, color = b, name = somethingelse.

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

Я написал этот метод:

def is_liked(self,user):
      return Car.likes.through.objects.filter(car__model=self.model, car__year=self.year, profile_id=user.id).exists()

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

1 Ответ

0 голосов
/ 05 мая 2020

Если определение вашей модели выглядит примерно так:

class Car(...):
   likes = models.ManyToManyField(User)
   model = models.CharField(...)
   year = models.IntegerField(...)

Вы можете попробовать это (используя distinct в Count):

from django.db.models import F, Count

cars = Car.objects.annotate(
    like_count=Count(
        'likes', 
        filter=Q(
            model=F('model'),
            year=F('year')
        ),
        distinct=True
    )
)
print(cars.values('model', 'year', 'like_count'))
...