Заполнить таблицу записями базы данных - PullRequest
0 голосов
/ 30 сентября 2019

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

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

Результат таблицы, который я пытаюсь получить:

В первом столбце указано время, когда было выполнено извлечение данных, а в верхнем столбце указано, на какие даты выполняется бронирование (дата заезда). Остальные - это цены.

    +--------+-------+-------+-------+-------+
    |        | 1Apr  | 2Apr  | 3Apr  | 4Apr  |      
    +--------+-------+-------+-------+-------+
    | 11am   | 40(A) | 40(A) | 40(A) | 40(A) |
    | 1110am | 40(X) | 40(X) | 42(A) | 42(A) |
    | 1120am |       |       |       |       |
    +--------+-------+-------+-------+-------+

Основная модель - это PriceDatum, где хранятся все цены, а другой важной моделью для этой таблицы является RoomScans, в которой хранится время, когда было выполнено сканирование.

models.py :

class PriceDatum(models.Model):
    room_scan = models.ForeignKey(RoomScan,default=1, on_delete=models.CASCADE)
    room = models.ForeignKey(Room, on_delete=models.CASCADE)
    checkin = models.DateField(db_index=True, help_text="Check in date", null=True)
    checkout = models.DateField(db_index=True, help_text="checkout date", null=True)
    price = models.PositiveSmallIntegerField(help_text="Price in the currency stated")
    refund_status = models.CharField(max_length=100, default="N/A")
    scanned = models.DateTimeField(db_index=True, help_text="Check in date", null=True)
    availability_count = models.PositiveSmallIntegerField(help_text="How many rooms are available for this price")
    max_people = models.PositiveSmallIntegerField(help_text="How many people can stay in the room for this price")
    meal = models.CharField(max_length=100, default="N/A", help_text="Tells if breakfast is included in room price")

class RoomScan(models.Model):
    property_scan = models.ForeignKey(PropertyScan, on_delete=models.CASCADE)
    room = models.ForeignKey(Room, on_delete=models.CASCADE, default=None)
    time_scanned = models.DateTimeField(auto_now_add=True, null=True)

class Room(TimeStampedModel):
    property = models.ForeignKey(Property, on_delete=models.CASCADE,
                             help_text="The BDC property in which the room is located")
    room_id = models.PositiveIntegerField(unique=True, help_text="The bdc_id is unique from bdc website", null=True)
    name = models.CharField(max_length=300, null=True, blank=True)

views.py

class AverageHistory(TemplateView):
template_name = "Scan/average.html"

def get_context_data(self, room_id=None, **kwargs):
    filter_class = RoomFilter
    ordering_fields = ('meal', 'refund', 'people')
    search_fields = ('meal', 'refund', 'people')
    selected_room = Room.objects.get(room_id=room_id)

    max_people_count = selected_room.pricedatum_set.all().aggregate(Max('max_people'))['max_people__max']
    meal_count = selected_room.pricedatum_set.filter(meal='not_included').count()

    # todo think how to handle unavailable rooms so we don't need query them separately and join queryset,
    if meal_count == 0:
        meal = 'included'
    else:
        meal = 'not_included'
    unavailable_rooms_prices = selected_room.pricedatum_set.filter(availability_count=0).distinct()

    available_rooms_prices = selected_room.pricedatum_set.filter(refund_status='refund', max_people=max_people_count,
                                                          meal=meal).order_by().order_by('checkin').distinct()
    x = len(available_rooms_prices)


    price_data = sorted(
        chain(unavailable_rooms_prices, available_rooms_prices),
        key=attrgetter('checkin'))
    ur_dates = list(unavailable_rooms_prices.values('checkin', 'checkout').distinct().order_by('checkin'))
    ar_dates = list(available_rooms_prices.values('checkin', 'checkout').distinct().order_by('checkin'))
    a = len(ar_dates)

    if ur_dates is not None:
        ar_dates.extend(ur_dates)


    col_count = list(range(len(ar_dates)))


    # todo: keep an eye if rooms might be only 'non_refundable' or 'partially_refundable', now we read only refundable one's
    #   because we need highest price.

    # Room list to have details about selected room to show the name on the template.
    room_list = []
    # Room dictionary to store details about room.
    room_name_dict = {
        'room': selected_room
    }

    room_scan = selected_room.roomscan_set.all()

    # Room dictionary appended to room list, so it can be added to data context.
    room_list.append(room_name_dict)

    ar_dates = sorted(ar_dates, key=lambda r: r['checkin'])

    context = {'room_details': room_list,
               'room_scan': room_scan,
               'price_data': price_data,
               'dates': ar_dates,
               'table': available_rooms_prices,
               'col_count': col_count
               }

    return context

template

<table class="table table-bordered table-striped">
<tbody>
    <tr>
        <td>
            Booking Dates >
            ##############
            Time Scanned v
        </td>
        {% for d in dates %}
            <td>
                {{ d.checkin|date:"d/m/y" }}-{{ d.checkout|date:"d/m/y" }}
            </td>
        {% endfor %}
    </tr>
    {% for i in room_scan %}
        <tr>
        <td>
            {{ i.time_scanned|date:"d/m/y h:i" }}
        </td>
        {% for x in col_count %}
            <td>
            {{ price_data|get_at_index:x}} [{{forloop.counter}}]
            </td>
        {% endfor %}
    {% endfor %}
    </tr>
    </tbody>
    </table>

Вопрос: Мой вопрос: как мне заполнить таблицу, чтобы каждая цена отображалась только в той строке, где она связана со временем очистки на левой стороне

Текущий результат:

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

Извините, если он слишком широк или недостаточно объяснен, попробовал мойлучший.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...