ManytoMany запрос и рендеринг шаблонов из одной модели в другую

Я новичок в Django. У меня возникло два разных вопроса.

  1. I can't query between one of my model and another model (ManyToMany). I can do this with the shell, but I couldn't handle it in the template.

  2. I cannot assign a default value from one model to another model's field.

На первый вопрос;

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

room[0].room_type_id.all()

Но я не могу сделать это в шаблоне. С другой стороны, когда я хочу показать его с помощью display, он возвращает пустое значение. Что я хочу сделать здесь; вернуть типы комнат для каждой комнаты или или получить доступ к room_cost класса RoomType и отобразить его в шаблоне, повторяя для каждого типа комнаты.

{% for room in rooms %}
    <h3 class="card-title pricing-card-title"> {{room.room_type_id_display}} </h3>
{% endfor %}

Мой второй вопрос:

Установить значение из свойства другой модели по умолчанию в поле другой модели. То есть, присвоить значение, возвращаемое из total_price модели Booking, полю price в модели Payment по умолчанию.

Буду признателен, если кто-нибудь сможет предоставить документацию или ресурсы по этому вопросу.

class RoomType(models.Model):
    ROOM_CHOICES = (
        ('1', 'O),
        ('2','T'),
        ('3', 'Th'),
        ('4','F'),
        ('5','Fi')
    )
    room_type = models.CharField(max_length=50,choices=ROOM_CHOICES)
    room_type_des = models.TextField(blank=True,null=True)
    room_cost = models.IntegerField()

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

class Room(models.Model):
    room_number = models.IntegerField()
    room_des = models.TextField(blank=True,null=True)
    room_availabe = models.BooleanField(default=True)
    room_type_id = models.ManyToManyField(RoomType)

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

class Booking(models.Model):
    room_number_id = models.ForeignKey(Room,on_delete=models.DO_NOTHING)
    customer_id = models.ManyToManyField(Customer)
    check_in = models.DateTimeField(auto_now_add=True)
    check_out = models.DateTimeField(auto_now_add=False,auto_now=False,auto_created=False, null=True)
    status = models.BooleanField(default=False)
    @property
    def calculate_day(self):
        day = self.check_out - self.check_in
        return str(day.days)
    
    @property
    def total_price(self):
        day = self.check_out - self.check_in
        price = self.room_number_id.room_type_id.room_cost
        return price*day.days
        

class Payment(models.Model):
    booking_id = models.ForeignKey(Booking,on_delete=models.DO_NOTHING)
    ACCEPT_CHOICES = (
        ('N','N'),
        ('K','K'), 
    )
    payment_type = models.CharField(max_length=1,choices=ACCEPT_CHOICES)
    price = models.IntegerField()
    payment_detail = models.TextField()

Вот небольшая модификация: не используйте "_id", потому что это не id, это реальный экземпляр иностранной модели. Затем используйте "related_name", и думайте так: "Если я начну с противоположной стороны, какое имя я должен использовать?" (оно всегда во множественном числе). Что касается (2), вы не можете установить значение по умолчанию для "промежуточной таблицы": поле ManyToMany создает таблицу "join" для соединения двух других таблиц. Вы можете установить значение по умолчанию только для полей OneToOne и ForeignKey

class RoomType(models.Model):
    ROOM_CHOICES = (
        ('1', 'O),
        ('2','T'),
        ('3', 'Th'),
        ('4','F'),
        ('5','Fi')
    )
    room_type = models.CharField(max_length=50,choices=ROOM_CHOICES)
    room_type_des = models.TextField(blank=True,null=True)
    room_cost = models.IntegerField()

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

class Room(models.Model):
    room_number = models.IntegerField()
    room_des = models.TextField(blank=True,null=True)
    room_availabe = models.BooleanField(default=True)
    room_type = models.ManyToManyField(RoomType, related_name="rooms")

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

class Booking(models.Model):
    room = models.ForeignKey(Room, related_name="bookings", on_delete=models.DO_NOTHING)
    customer = models.ManyToManyField(Customer, related_name="bookings")
    check_in = models.DateTimeField(auto_now_add=True)
    check_out = models.DateTimeField(auto_now_add=False,auto_now=False,auto_created=False, null=True)
    status = models.BooleanField(default=False)
    @property
    def calculate_day(self):
        day = self.check_out - self.check_in
        return str(day.days)
    
    @property
    def total_price(self):
        day = self.check_out - self.check_in
        price = self.room_number.room_type.room_cost
        return price * day.days
        

class Payment(models.Model):
    booking = models.ForeignKey(Booking, related_name="payments", on_delete=models.DO_NOTHING)
    ACCEPT_CHOICES = (
        ('N','N'),
        ('K','K'), 
    )
    payment_type = models.CharField(max_length=1,choices=ACCEPT_CHOICES)
    price = models.IntegerField()
    payment_detail = models.TextField()

Если вам нужны все типы комнат, то это:

RoomType.objects.all()

Если вы хотите "отправить" все типы в шаблон, используйте get_context_data следующим образом:

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context["room_types"] = RoomType.objects.all()
    return context

и в вашем шаблоне:

 {% for room_type in room_types %}
     {{ room_type }}
 {% endfor %}

Для вашего шаблона (и с моим кодом модели выше), вы могли бы сделать:

{% for room in rooms %}
    <h3 class="card-title pricing-card-title"> {{ room.room_type }} </h3>
{% endfor %}

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

Вернуться на верх