我正在尝试从数据库中填充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
模板
<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列表中打印它们,所以我需要对模板甚至视图进行一些过滤。
很抱歉,如果它太宽泛或解释不充分,请尽我所能。