class Beverage(models.Model):
name=models.CharField(max_length=255)
def __unicode__(self):
return self.name
class Location(models.Model):
name=models.CharField(max_length=255)
beverages = models.ManyToManyField(Beverage, through='LocationStandard')
location_number=models.CharField(max_length=255)
organization=models.CharField(max_length=255)
def __unicode__(self):
return self.name
class LocationStandard(models.Model):
beverage=models.ForeignKey(Beverage)
location=models.ForeignKey(Location) #elim this or m2m
start_units=models.IntegerField()
fill_to_standard=models.IntegerField(max_length=10)
order_when_below=models.IntegerField(max_length=10)
class Order(models.Model):
location=models.ForeignKey(Location) #elim this or m2m
beverage=models.ForeignKey(Beverage)
units_ordered=models.IntegerField(max_length=10, default=0)
order_delivered=models.BooleanField(default=False)
timestamp=models.DateTimeField(auto_now_add=True)
user=models.ForeignKey(User)
How can I generate a report that will get me an HTML table with all locations on the x-axis and all beverages on the y-axis. The main thing I am struggling with is just what to query that I can pass the template that I can loop over. Thoughts?
You can't get them in one query, but you can make something like that (don't want to setup a whole env to test, so use it as a clue, not a working solution):
# you can't do order_by in a template, either do them in the view, or
# make methods in the model, or make it the Meta default ordering
# print the header, and make sure we got a list of all beverage cached
beverages = Beverage.objects.order_by('name')
for beverage in beverages:
print each cell of your header
# print a row for each location
locations = Location.objects.all()
for location in locations:
print the location name table cell
location_beverages = iter(location.beverages.order_by('name'))
# for each beverage, we print a cell. If the beverage is in the
# location beverage list, we print a checked cell
# we use the fact that queryset are iterable to move the cursor
# only when there is a match
cur_bev = location_beverages.next()
for beverage in beverages:
if beverage == cur_bev:
print checked table cell
cur_bev = location_beverages.next()
else:
print empty table cell
The intermediary variables to store querysets are very important, as they allow you to benefit from Django queryset cache.
With Django 1.4 or more, you can replace:
locations = Location.objects.all()
By:
locations = Location.objects.prefetch_related('beverages')
To get a serious perf boost.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With