Как отфильтровать профили, у которых есть встреча (связь по внешнему ключу)? - PullRequest
1 голос
/ 04 октября 2019

Я пытаюсь получить все Profile объекты, для которых не запланировано Appointment. Appointment объект может иметь или не иметь ассоциированный с ним Profile (будь то пустой временной интервал или забронированная встреча).

Я еще ничего не пробовал, потому что не знаюс чего начать.

users / models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone = models.CharField(max_length=30)
    objects = managers.ProfileManager()

booking / models.py

class Appointment(models.Model):
    profile = models.ForeignKey(
        'users.Profile',
        on_delete=models.PROTECT,
        unique=False,
        null=True,
    )
    massage = models.CharField(
        default=None,
        max_length=2,
        choices=[
            ('SW', 'Swedish'),
            ('DT', 'Deep Tissue'),
        ],
        null=True,
    )
    date_start = models.DateTimeField()
    date_end = models.DateTimeField()
    black_out = models.BooleanField(default=False)
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)
    objects = AppointmentManager()

users / Manager.py

def search_by_name(self, request):
    first_name = request.GET.get('first-name', '')
    last_name = request.GET.get('last-name', '')

    profiles = []
    max_results = 5
    if first_name == '' and last_name == '':
        return (True, {'profiles': profiles})
    elif last_name == '':
        profiles = models.Profile.objects \
            .filter(user__first_name__icontains=first_name)[:max_results]
    elif first_name == '':
        profiles = models.Profile.objects \
            .filter(user__last_name__icontains=last_name)[:max_results]
    else:
        profiles = models.Profile.objects \
            .filter(user__first_name__icontains=first_name) \
            .filter(user__last_name__icontains=last_name)[:max_results]

    return (True, {'profiles': profiles})

Функция search_by_name фильтрует все Profile объекты, содержащие имена и / или фамилии, включая объекты с запланированным Appointment (что мне не нужно).

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 04 октября 2019

Вы можете получить профили, которые не имеют встречу с:

Profile.objects.filter(<b>appointment=None</b>)

Так что вы можете, например, фильтровать с:

def search_by_name(self, request):
    first_name = request.GET.get('first-name')
    last_name = request.GET.get('last-name')
    max_results = 5
    filter = {}
    if first_name:
        filter['user__first_name__icontains'] = first_name
    if last_name:
        filter['user__last_name__icontains'] = first_name
    profiles = models.Profile.objects.filter(
        <b>appointment=None</b>,
        **filter
    )
    return (True, {'profiles': profiles})
...