Запросы Django для ManyToManyFields

Я пытаюсь сделать клон приложения для знакомств и пытаюсь получить профили, которые соответствуют условиям пользователя. Я создал модель Profile, которая много-ко-многим сама с собой, и модель Match, которая объединяет 'liker' и 'likee' и добавляет дополнительные поля. Я пытаюсь получить все профили, которые я еще не пролистал. Я смог сделать это с помощью нескольких обращений к базе данных, но хочу знать, есть ли способ сделать это с помощью одного/нескольких запросов.

мои модели выглядят следующим образом

class Profile(models.Model):

  class MatchGenderChoices(models.TextChoices):
    FEMALE = 'FEMALE'
    MALE = 'MALE'
    ALL = 'ALL'

  class GenderChoices(models.TextChoices):
      FEMALE = 'FEMALE'
      MALE = 'MALE'
      NONBINARY = 'NONBINARY'
  display_name = models.CharField(max_length=30, null=True)
  age = models.IntegerField(null=True, blank=False)
  gender = models.CharField(max_length=10, choices = GenderChoices.choices, null = True, blank = False)
  user = models.OneToOneField(User, on_delete=models.CASCADE)
  liked_profiles = models.ManyToManyField('self', through= 'Match')
  match_distance = models.IntegerField(default = 30)
  match_age_max = models.IntegerField(default = 99)
  match_age_min = models.IntegerField(default = 18)
  match_gender =  models.CharField(max_length=10, choices = MatchGenderChoices.choices, null = True, blank = False)

  city = models.CharField(max_length=30, null=True)
  latitude = models.DecimalField(max_digits=10, decimal_places=6, null = True)
  longitude = models.DecimalField(max_digits=10, decimal_places=6, null = True)
  age = models.IntegerField(null=True, blank=False,validators=[MinValueValidator(MIN_AGE), MaxValueValidator(MAX_AGE)])
  bio = models.TextField(max_length=5000, default = "Add a bio", null = True)
  profile_picture_url = models.ImageField(default = os.path.join( "media", "images","default_profile_picture.jpg"), blank = True, upload_to = "images/")



@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()


class Match(models.Model):
  liker = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name = "liker")
  likee = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name = "likee", null = True)
  match = models.BooleanField(default= False)
  date_liked= models.DateField(auto_now=True)
  date_confirmed =models.DateField(null= True, blank = True)
  class Meta:
    unique_together = [['liker', 'likee']]

и то, как я реализую получение этой "колоды" профилей, выглядит следующим образом


def get_profiles(profile):
  # returns list of profiles where the age and genders match the user's choices
  exclude_id_list = [profile.id]
  exclude_id_list.extend(list(Match.objects.filter(liker_id =profile.id).values_list('likee_id', flat=True)))
  exclude_id_list.extend( list(Match.objects.filter(Q(likee_id=profile.id) & ~Q(date_confirmed__isnull=True) ).values_list('liker_id', flat=True)))
  if profile.match_gender == 'ALL':
    matches = Profile.objects.exclude(id__in = exclude_id_list).filter(Q(age__lte=profile.match_age_max) & Q(age__gte=profile.match_age_min))
  else:
    matches = Profile.objects.exclude(id__in = exclude_id_list).filter(Q(age__lte=profile.match_age_max) & Q(age__gte=profile.match_age_min) & Q(gender=profile.match_gender))

Я почти уверен, что делаю что-то совершенно неправильно, но я совершенно не понимаю, с чего начать.

вот пример того, как можно работать со многими ко многим:

class A(models.Model):
      name= models.CharField(...)

class B(models.Model):
      a= models.ManyToManyField(A)

вы можете получить доступ к данным таким образом:

model_b_object.a.all()

или

A.objects.filter(b=model_b_object)
Вернуться на верх