Django ORM лучший способ манипулировать запросом django ORM

#python #django #django-models #django-views #django-orm

Вопрос:

Ниже приведены модели:

 class Seat(models.Model):
    hall = models.ForeignKey(Hall,on_delete=CASCADE)
    type = models.TextField(verbose_name="Seat Type")

class Show(models.Model):
    show_time = models.TimeField(verbose_name='Show Time')
    movie = models.ForeignKey(Movie,on_delete=CASCADE)
    hall = models.ForeignKey(Hall,on_delete=CASCADE)
    cinema = models.ForeignKey(Cinema,on_delete=CASCADE)

class Booking(models.Model):
    seat = models.ForeignKey(Seat,on_delete=CASCADE)
    show = models.ForeignKey(Show,on_delete=CASCADE)
    movie = models.ForeignKey(Movie,on_delete=CASCADE)
    hall = models.ForeignKey(Hall,on_delete=CASCADE)
    cinema = models.ForeignKey(Cinema,on_delete=CASCADE)
    user = models.ForeignKey(User, verbose_name="Username", on_delete=DO_NOTHING) # donothing
 

Объяснение моделей:

Несколько мест в зале

В каждом зале проходит несколько шоу

Каждое бронирование-это в основном билет на шоу с определенным местом и конкретным шоу.

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

SQL — запрос будет выглядеть следующим образом:

 SELECT * FROM Seat as S join Show as Sh on S.hall = Sh.hall join Bookings as B on B.show = Sh.id where Sh.id = 1 AND B.seat IS NULL
 

как преобразовать это в Django ORM:

в состоянии сделать это так (есть ли лучший способ, чем создание списка идентификаторов мест?):

             qs = Seat.objects.filter(hall=hid) #----------------------------------
            show_bookings = Booking.objects.filter(show=spk)
            seat_id_list = []

            for each_booking in show_bookings:
                print(each_booking.seat.id)
                seat_id_list.append(each_booking.seat.id)
            qss = Seat.objects.exclude(id__in = seat_id_list)

 

Ответ №1:

Вы можете получить эти Seat s с помощью:

 Seat.objects.filter(hall=hid).exclude(booking__show=spk) 

Это приведет к получению всех Seat s для данного Hall объекта hid , где нет Booking для Show определенного spk объектом.

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

1. Большое спасибо, это хорошо сработало. Что здесь означает бронирование ? это не поле ни в модели сиденья, ни в модели шоу? также модель называется Booking .

2. @akashdeep: Если вы определяете a ForeignKey , Django определяет отношение в обратном порядке. По умолчанию он используется в качестве related_query_name имени модели, в которой вы определяете его в нижнем регистре, чтобы вы могли получить доступ к соответствующим бронированиям в запросе booking .