I'm new to Django. I had two different questions.
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.
I cannot assign a default value from one model to another model's field.
For the first question;
What I want to do is show values for multiple options. For this, I could make a query similar to this in the shell:
room[0].room_type_id.all()
But I can't do this in the template. On the other hand, when I want to show it with display, it returns empty. What I want to do here; returning the room types for each room or or accessing the room_cost of the RoomType class and displaying it in the template, repeated for each room type.
{% for room in rooms %}
<h3 > {{room.room_type_id_display}} </h3>
{% endfor %}
My second question is;
To set the value from the property of a different model as default in the other model field. That is, to assign the value returned from the total_price of the Booking model to the price field in the Payment model by default.
I would appreciate it if anyone could provide documentation or resources on the subject.
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()
CodePudding user response:
Here's a small modification: don't use "_id
", because it's not an id
, it's a real instance of the foreign model.
Then, use "related_name
", and think like "if I start from the opposite side, what name should I use?" (it's always plural).
And for your (2), you can't set a default value for a "in-between table": a ManyToMany field create a "join" table to join the two other tables. You can only set a default value for OneToOne and ForeignKey fields.
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()
If you want all your room types, it's:
RoomType.objects.all()
If you want to "send" all types to a template, use get_context_data
like this:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["room_types"] = RoomType.objects.all()
return context
and in your template:
{% for room_type in room_types %}
{{ room_type }}
{% endfor %}
For your template (and with my models code above), you could do:
{% for room in rooms %}
<h3 > {{ room.room_type }} </h3>
{% endfor %}
And if you want to show all options in a form, it's another subject, too long for a simple answer here, read the official documentation here.