0

I am making a hotell-page, and have made models for bookings and rooms. I want to display the bookings related to a room in a table, and have the related bookings laying under the spesific room.the table for rooms and bookings

I show the code from the views.py file here:

def vaskehjelp(response):
available_rooms = Room.objects.filter(available=True)
room_nums = []
context = {}
for room in available_rooms:
    related_bookings = Booking.objects.filter(room=room)
    if related_bookings:
        room_nums.append(room.room_no)
        context[room.room_no] = related_bookings

context["room_nums"] = room_nums
context["available_rooms"] = available_rooms
print(context)
return render(response, "../templates/se_vaskbare_rom.html", context)

and the code from my template file here:

<table class="table table-striped table-dark">
            <tr class="thead-dark">
                <th scope="col">Room No.</th>
                <th scope="col">Capacity</th>
                <th scope="col">Room Type</th>
            </tr>
            {% for item in available_rooms %}
                <tr scope="row">
                    <td>{{ item.room_no }}</td>
                    <td>{{ item.capacity }}</td>
                    <td>{{ item.room_type }}</td>
                </tr>
                {% if item.room_no in room_nums %}
                    {% for booking in item.room_no %}
                        <h1></h1>
                        <tr scope="row">
                            <td>{{ booking.cin_date }}</td>
                            <td>ku</td>
                            <td>{{ booking.cout_date }}</td>
                        </tr>
                    {% endfor %}
                {% endif %}
            {% endfor %}
        </table>

The problem is that the booking-element in the template code doesent seem to work. I dont manage to access the lists of bookings related to the current selected room. As you see i have an outer for loop to iterate over the rooms, and then the inner for loop iterate over the related bookings (only in case that room is in the "room_nums" list. The problem is (i think) that the for booking in item.room_no doesnt work, i dont get any info from the booking variable at least...

In the table i should have had the check in and check out dates in the left and right column, but i dont get this information from the booking variable...

ps: the idea is that item.room_no is referrering to a list in the context dictionary. I have tried other things, but this is the closest i have come.

Here are the models:

class Room(models.Model):
room_choices = [('S', 'Single Occupancy'), ('D', 'Double Occupancy'), ('F', 'Firemannsrom')]
room_no = models.CharField(max_length=5)  # primary key
available = models.BooleanField(default=False)
capacity = models.IntegerField(default=None)
room_type = models.CharField(choices=room_choices, max_length=1, default=None)
price = models.IntegerField( blank=True, null=True)

def __str__(self):
    return "Romnr: " + str(self.room_no) + " -- type:" + str(self.room_type)

and

class Booking(models.Model):
#defaultRom = Room.objects.get(room_no='100')
#defaultRomID = defaultRom.id
room_choices = [('S', 'Single Occupancy'), ('D', 'Double Occupancy'), ('F', 'Firemannsrom')]
bookingid = models.AutoField(db_column='BookingID', primary_key=True)  # Field name made lowercase.
guest = models.ForeignKey('auth.User', on_delete=models.CASCADE)  # eller settings.AUTH_USER_MODEL
cin_date = models.DateField(db_column='CIN_Date', blank=True, null=True,
                                verbose_name='Check-In Date')  # Field name made lowercase.
cout_date = models.DateField(db_column='COUT_Date', blank=True, null=True,
                                 verbose_name='Check-Out Date')  # Field name made lowercase.
room_type = models.CharField(choices=room_choices, max_length=1, default=None)
room = models.ForeignKey('Room', on_delete=models.CASCADE, db_column='Room', default=None)

class Meta:
    managed = True
    db_table = 'Booking'

def __str__(self):
    return "Bruker: " + self.guest.__str__() + " -- id:" + str(self.bookingid) + " -- Inndato: " +  self.cin_date.__str__() + " -- Utdato: " + self.cout_date.__str__() + " -- " + self.room.__str__()

Here is the the result of print(context):

{'100': <QuerySet [<Booking: Bruker: email -- id:27 -- Inndato: 2020-03-27 -- Utdato: 2020-03-29 -- Romnr: 100 -- type:S>]>, '103': <QuerySet [<Booking: Bruker: olaNordmann -- id:26 -- Inndato: 2020-03-07 -- Utdato: 2020-03-15 -- Romnr: 103 -- type:D>]>, 'room_nums': ['100', '103'], 'available_rooms': <QuerySet [<Room: Romnr: 100 -- type:S>, <Room: Romnr: 103 -- type:D>, <Room: Romnr: 106 -- type:F>, <Room: Romnr: 101 -- type:S>]>}

Thanks in advance!

3
  • are you sure that related_bookings does not return empty queryset? So that you do not any any items to browse using django templates. Moreover, can you give me definition of Room and Booking classes? Commented Mar 13, 2020 at 20:04
  • Yes i will add them now! I have printed the result of the context-list, and it is full of informations yes! Added now. Commented Mar 13, 2020 at 20:08
  • I added the print(context) result as well now. Commented Mar 13, 2020 at 20:17

1 Answer 1

1

You are referencing to CharField defined in Room class instead of Booking queryset

a quick solution might be to change the code in a following way:

{% for booking in item.related_bookings %}
    <h1></h1>
    <tr scope="row">
        <td>{{ booking.cin_date }}</td>
        <td>ku</td>
        <td>{{ booking.cout_date }}</td>
    </tr>
{% endfor %}
def vaskehjelp(response):
    available_rooms = Room.objects.filter(available=True)
    context = {}
    for room in available_rooms:
        related_bookings = Booking.objects.filter(room=room)
        if related_bookings:
            room_nums.append(room.room_no)
            room.related_bookings = related_bookings

    context["room_nums"] = room_nums
    context["available_rooms"] = available_rooms
    print(context)
    return render(response, "../templates/se_vaskbare_rom.html", context)

But I believe that the easiest solution is the following one:

def vaskehjelp(response):
    context = {}
    available_rooms = Room.objects.filter(available=True).prefetch_related('Room')
    context["available_rooms"] = available_rooms
    return render(response, "../templates/se_vaskbare_rom.html", context)
{% for item in available_rooms %}
    <tr scope="row">
        <td>{{ item.room_no }}</td>
        <td>{{ item.capacity }}</td>
        <td>{{ item.room_type }}</td>
    </tr>
    {% for booking in item.Room %}
        <h1></h1>
        <tr scope="row">
            <td>{{ booking.cin_date }}</td>
            <td>ku</td>
            <td>{{ booking.cout_date }}</td>
        </tr>
    {% endfor %}
{% endfor %}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! The first suggestion worked, i only had to change 8th line in the "vaskehjelp"-function, but i think this was what you ment! The other suggestion didnt work, or at least it gives me this error: Cannot find 'Room' on Room object, 'Room' is an invalid parameter to prefetch_related()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.