I'm trying to learn Django and web development aspects and have set myself a challenge of writing some 3rd party tools for the popular action RPG, Path of Exile.
A key feature of any ARPG is collecting loot items, which may have any number of 'stats', these are represented in the model as a ManyToManyField. I'd like to list a group of items and their stats in table. I know how to do this with HTML tags in the relevant template.html but would like to use django_tables2 if possible, to reduce repetition etc.
I've played around a bit and read the documentation and the tables.html template but can't see an obvious way of doing this or find any other posts etc, I'd be grateful for any help or a nudge in the right direction.
Here is a mockup of what I'd like the table to look like I'm not too bothered about having cell dividers or not but would like to be able to sort the columns of these many to many aspects.
modely.py
class Stats(models.Model):
name = models.ForeignKey(StatNames, models.DO_NOTHING)
min_value = models.IntegerField()
max_value = models.IntegerField()
class ItemName(models.Model):
name = models.CharField(unique=True, max_length=50)
i_level = models.SmallIntegerField()
min_dmg = models.SmallIntegerField(blank=True, null=True)
max_dmg = models.SmallIntegerField(blank=True, null=True)
stats = models.ManyToManyField(Stats)
tables.py
class ItemTable(tables.Table):
class Meta:
model = poe.models.ItemName
print("ItemName.type", poe.models.ItemName.type)
fields = (
'name',
'i_level',
'stat_name',
'min_value',
'max_value',
)
Here's an example of the html approach I tried out, the variable names are a little different from above but it demonstrates what I had in mind.
<table>
<thead>
<tr>
<th>Name</th>
<th>Something</th>
<th>Something Else</th>
<th colspan='3'>Stats!</th>
</tr>
</thead>
<tbody>
{% for obj in object_list %}
{% with obj.stats.count|default:1 as rowspan %}
<tr>
<td rowspan='{{rowspan}}'>{{obj.name}}</td>
<td rowspan='{{rowspan}}'>{{obj.something}}</td>
<td rowspan='{{rowspan}}'>{{obj.something_else}}</td>
{% for stat in obj.stats.all %}
<td>{{stat.name}}</td>
<td>{{stat.min_value}}</td>
<td>{{stat.max_value}}</td>
{% empty %}
<td colspan='3'>No stats</td>
{% endfor %}
</tr>
{% endwith %}
{% endfor %}
</tbody>
</table>
Related
I'm hoping I can get a little guidance.
I'm trying to return data from 3 related tables in my template. In SQL, this is a simple approach, but the Django requirements have me stumbling.
I'd like to display information similar to this:
WaiverAdult.first_name CheckIn.checkintime
WaiverMinor.first_name CheckIn.checkintime
WaiverAdult.first_name CheckIn.checkintime
WaiverMinor.first_name CheckIn.checkintime
WaiverMinor.first_name CheckIn.checkintime
Here are a simplified representation of the models with the relationships defined.
class WaiverAdult(models.Model):
first_name = models.CharField(max_length=50, blank=True)
class WaiverMinor(models.Model):
first_name = models.CharField(max_length=50, blank=True)
parent = models.ForeignKey(WaiverAdult, on_delete=models.CASCADE)
class CheckIns(models.Model):
adult = models.ForeignKey(WaiverParent, on_delete=models.CASCADE, blank=True, null=True)
minor = models.ForeignKey(WaiverChild, on_delete=models.CASCADE, blank=True, null=True)
checkintime = models.DateTimeField(auto_now_add=True)
Here is my simplified view:
class WaiverListView(ListView):
waiver_adults = WaiverAdult.objects.all().prefetch_related(
'waiverminor_set').order_by('created')
queryset = waiver_adults
context_object_name = "waiver_list"
template_name = 'waiver/waiver_list.html'
And, this is my template.
{% for adult in waiver_list %}
<tr>
<td>{{adult.first_name}}</td>
<td>insert the adult checkin time here</td>
</tr>
{% for child in adult.waiverminor_set.all %}
<tr>
<td>{{child.first_name}}</td>
<td>insert the child checkin time here</td>
</tr>
{% endfor %}
{% endfor %}
I would be very appreciative of details in the explanations as I really want to understand how this all works.
Firstly, for every Foreign key you are creating I suggest you to add a related_name this way you specify the name of reverse relation ship between the children model and parent model in your case for example, your code should be:
class WaiverAdult(models.Model):
first_name = models.CharField(max_length=50, blank=True)
class WaiverMinor(models.Model):
first_name = models.CharField(max_length=50, blank=True)
parent = models.ForeignKey(WaiverAdult, on_delete=models.CASCADE,related_name='minor_of_adult')
and let's explain how does it work, you want to know and get all the minors of some adult, what you should do is specify the adult, and get all minor related to that adult, in code context (try it in django shell, using python manage.py shell):
adult = WaiverAdult.objects.get(first_name='cbirch') #specifying the adult
adult.minor_of_adult.all() #notice how we access the minor using the related_name
same thing apply to the last model CheckIns.
With the models you have created it is possible to have multiple checkin times per parent and child so you need to loop through the list. Also your foreign keys refer to WaiverParent and WaiverChild whilst the actual model names are WaiverAdult and WaiverMinor. You could try the following template:
{% for adult in waiver_list %}
<tr>
<td>{{adult.first_name}}</td>
<td>
{% for checkin in adult.checkins_set.all %}
{{ checkin.checkintime }}
{% endfor %}
</td>
</tr>
{% for child in adult.waiverminor_set.all %}
<tr>
<td>{{child.first_name}}</td>
<td>
{% for checkin in child.parent.checkins_set.all %}
{{ checkin.checkintime }}
{% endfor %}
</td>
</tr>
{% endfor %}
{% endfor %}
hello family by the way I am a beginner in web programming with the python language and its django framework
my concern is to be able to display the information coming from the join of several tables or models in my case I have the following tables:
Country table
city table
church table
but I used the mptt for country and city and everything is working fine but I want to display the list of all the countries with their respective cities as well as all the churches for each city. this is where the great difficulty lies for the month. If there is someone who can help me I will be very very happy
Have something like this in your view, where you pass in your tables:
def TestView(request):
#...
countries = CountryModel.objects.all()
cities = CitiesModel.objects.all()
churches = ChurchesModel.objects.all()
#...
And then in your template, you can format these to seem like they are part of the same table. Use for loops to go through the models in your database. For example something like this should make a table with all of the items (assuming name is a parameter of the model:
<table>
<tr>
<td>Countries: </td>
{% for country in countries %}
<td>{{ country.name}}</td>
{% endfor %}
</tr>
<tr>
<td>Cities: </td>
{% for city in cities %}
<td>{{ city.name}}</td>
{% endfor %}
</tr>
<tr>
<td>Churches: </td>
{% for church in churches %}
<td>{{ church.name}}</td>
{% endfor %}
</tr>
</table>
This is driving me mad (I really have looked everywhere - but I know it must be easy and I'm just being a tad think)
How do I add a filter to a child of a parent (one to many)? The code below provides a list of companies in a table, then on the same page/ table, each company has a list of "charges" which is attributed to that company; thanks to the ForeignKey and using "charge_set" it works great. However, I would like to add a filter to the "charges" for status (so exclude "outstanding" status)
In ROR I would have simply placed the following
<% company.charges.where(status: "Outstanding").each do |charge| %>
AIUI, I can't do this with Python/ Django in the view; so how would I go about adding a simple filter to the child of the parent within this loop?
from django.db import models
class Company(models.Model):
name = models.CharField(max_length=100)
class Charge(models.Model):
company = models.ForeignKey(Company, on_delete=models.CASCADE)
charge_id = models.CharField(max_length=100)
status = models.CharField(max_length=100)
from django.shortcuts import render
from companies.models import Company, Charge, Filing
from django.http import HttpResponse
def watch_list(request):
companies = Company.objects.order_by('-data_date')
return render(request,'company_watch/watch_list.html',{'companies':companies})
{% for company in companies %}
<tr>
<td>{{company.name}}</td>
<td>
<ul>
{% for charge in company.charge_set.all %}
<li>{{charge.charge_id}}</li>
{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
You can just grab the company and filter the children. If you want to the children on the backend:
company = Company.objects.get('...')
outstanding_children = Charge.objects.filter(company = company, status = "Outstanding")
If you want to display the children on the frontend:
{% for company in companies %}
<tr>
<td>{{company.name}}</td>
<td>
<ul>
{% for charge in company.charge_set.all %}
{% if charge.status == "Outstanding" %}
<li>{{charge.charge_id}}</li>
{% endif %}
{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
I am using a Django model to represent day-hour combinations. The goal is to render a matrix-like form with the days on the x-axis and the hours on the y-axis. The user can check each combination to define when a vehicle is available during a week.
The model looks as follows:
class TimeMatrix(models.Model):
MO00 = models.BooleanField(default=False)
MO01 = models.BooleanField(default=False)
MO02 = models.BooleanField(default=False)
MO03 = models.BooleanField(default=False)
....
SO22 = models.BooleanField(default=False)
SO23 = models.BooleanField(default=False)
I like to render the corresponding form coming from the CreateView as the mentioned matrix. The html to do this requires a list of days = ['MON', 'TUE', ..., 'SUN'] and hours = ['00', '01', ..., '23'] in order to render the form dynamically. The following html shows this without using the form the Django CreateView provides:
<form action="#">
<div class="table-responsive">
<table class="table">
<thead class="thead-light">
<tr>
<th scope="col">Day</th>
{% for h in hours %}
<th scope="col">{{h}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for d in days %}
<tr>
<th scope="row" class="wt-col">{{d}}</th>
{% for h in hours %}
<td><input type="checkbox" name="{{d}}{{h}}" value="{{d}}{{h}}" id="id_{{d}}{{h}}"></td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</form>
Since I like to use the security measures build into Django forms I like this to make use of the form the CreateView provides. Following this explanation, the individual form can be accessed using form.<field_name>. Combining this with the html would require a dynamic way to access the form fields, which for me raises two questions:
Following this advice I was able to implement getattr functionality for the templates which works with my models, but fails on the form the CreateView provides (e.g. {{form|getattribute:'MON00'}}). What am I missing?
Since I cannot concat the day and hour string in the template ({{form|getattribute:d+h}} will not work), what is a suitable way to access the required form field?
I'm not sure the best way to explain it so I created an example picture and made up some data:
I looked at this post and know I need to use some forloop template stuff: Displaying a Table in Django from Database
The parts that are throwing me off are how to have a table within a table. For example, the doctor 'Bob" has 3 different patients. Bob has one row but Bob's patient column has 3 rows within it.
<table class="table table-striped table-bordered">
<thead>
<th>Name</th>
<th>Total Patient Meetings</th>
<th>Patient</th>
<th>Meetings for Patient</th>
</thread>
<tbody>
{% for doctor in query_results %}
<tr>
<td> {{ doctor.name }} </td>
<td> {{ doctor.total_meetings }}</td>
//*Would I have a nested forloop in here?*//
{% for patient in query_results2 %}
<td> {{patient.name }} </td>
<td> {{patient.meeting_number }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
I'm having trouble finding an example like this to work off of and am not sure how to approach it.
I also need those patients to link to the individual patient pages. So if I click on Bob's patient 'C755' I will be directed to that patient's page. I was thinking something like:
`<p>{{patient.name}}:</p>`
Thanks for any help. Just not sure the best way to approach this.
"A 'related manager' is a manager used in a one-to-many or many-to-many
related context."
https://docs.djangoproject.com/en/1.10/ref/models/relations/
I can't see how your relation between doctor and patient is, but supposing it is something like this:
class Patient(models.Model):
name = models.CharField(max_length=50)
class Doctor(models.Model):
patient = models.ManyToManyField(Patient, verbose_name='patients')
You can easly iterate over doctor.patient using:
{% for doctor in doctors %}
{% for patient in doctor.patients.all %}
{{ patient.name }}
{% endfor %}
{% endfor %}
If you don't have a verbose_name attribute for the relation, then instead of using doctor.patients.all you use doctor.patients_set.all.
And to the patient's page, you can use a method inside your class Patient to easly do this:
{{ patient.name }}
"with get_absolute_url on your model it can make dealing with them on a per-object basis much simpler and cleaner across your entire site"
https://godjango.com/67-understanding-get_absolute_url/