Как получить информацию из трех разных таблиц одновременно? - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть следующие модели:

class Device(models.Model):
    name = models.CharField(max_length=100, blank=False)
    description = models.TextField(max_length=500, blank=True)
    ip_address = models.GenericIPAddressField(blank=True, null=True)
    contact_person = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    team = models.ForeignKey(Team, on_delete=models.SET_NULL, null=True)
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)

    def __str__(self):
        return self.name

class TimeSlot(models.Model):
    name = models.CharField(max_length=20)
    start_slot = models.CharField(max_length=10)
    end_slot = models.CharField(max_length=10)

    def __str__(self):
        return self.name


class Reservation(models.Model):
    device = models.ForeignKey(Device, on_delete=models.CASCADE)
    time_slot = models.ForeignKey(TimeSlot, on_delete=models.CASCADE)
    date_of_reservation = models.DateField()
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return "{} - {} for device: {} by {}.".format(self.time_slot, self.date_of_reservation, self.device, self.user)


class ForbiddenSlot(models.Model):
    device = models.ForeignKey(Device, on_delete=models.CASCADE)
    time_slot = models.ForeignKey(TimeSlot, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.time_slot)

Это простая система бронирования. У меня есть проблема, чтобы понять, как создать запрос для трех разных таблиц. Я хочу получить все временные интервалы, которые не установлены в ForbiddenSlot и Reservation для данного имени устройства.

Ответы [ 3 ]

0 голосов
/ 07 ноября 2019

Я думаю, что изменение структуры ваших моделей будет намного лучше, например, удаление модели ForbiddenSlot и замена ее флагом на модели резервирования, тогда вы можете выбрать все временные интервалы из модели резервирования, где запрещенный флаг равен False, например: reservations = Reservation.objects.only('time_slot').filter(device__name=name_of_the_device,forbidden=False), где forbidden - логическое поле.

0 голосов
/ 07 ноября 2019

Использование select_related () предварительно заполнит соответствующие атрибуты:

Model.objects.select_related()
0 голосов
/ 07 ноября 2019

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

TimeSlot.objects.filter(
    forbiddenslot__isnull=True,
    reservation__device__name='Device Name',
)

Это не обязательно самая легкая вещь для меня, чтобы обернуть голову, ноTimeSlot не только имеет доступ к .forbiddenslot_set, но также может фильтровать по forbiddenslot. То же самое касается reservation.

...