Django ForeignKey in ManytoMany field is displayed as None - django

I got a model that uses a foreignkey in a manytomany field:
class DefinitionTag(models.Model):
tag = models.CharField(max_length=50, default="Tag")
def __str__(self):
return self.tag
class Definition(models.Model):
name = models.CharField(max_length=100)
definition = models.CharField(max_length=1000)
fundstellen = models.CharField(max_length=300, blank=True)
wissenswertes = models.CharField(max_length=1000, blank=True)
tags = models.ManyToManyField(DefinitionTag)
def __str__(self):
return self.name
this works, and in the admin everything is set up so i can use it. The problem is if i try to display a table with the database entries in my view with the code:
def home(request):
query_results = Definition.objects.all()
context = {
"query_results": query_results
}
return render(request, 'home.html', context)
and in html:
{% for item in query_results %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.definition }}</td>
<td>{{ item.fundstellen }}</td>
<td>{{ item.wissenswertes }}</td>
<td>{{ item.tags }}</td>
</tr>
{% endfor %}
In the tag column it gives me only:
DefinitionTag.None
How can i display there all the tags choosen in the manytomany field?
I hope i'll get a hint!
Thanks

You need to loop on the m2m field to get all tags. Just referring to it won't give you individual tags that link to it:
{% for item in query_results %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.definition }}</td>
<td>{{ item.fundstellen }}</td>
<td>{{ item.wissenswertes }}</td>
<td>
{% for tag in item.tags.all %}
{{ tag }}
{% endfor %}
</td>
</tr>
{% endfor %}
If you are not sure how to get all items from m2m field, check out django doc.

Try looping through the tag:
{% for tag in item.tags.all %}
{{ tag }}
{% endfor %}

Related

don't show images from ImageField in django template

Django doesn't show images from ImageField in a template.
models.py
class Employee(models.Model):
emp_name = models.CharField(max_length=200)
emp_email = models.EmailField()
emp_contact = models.CharField(max_length=20)
emp_role = models.CharField(max_length=200)
emp_salary = models.IntegerField()
venue_image = models.ImageField(null=True, blank=True, upload_to="images/")
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
def __str__(self):
return self.emp_name
template:
<tbody>
{% for emp in employees %}
<tr>
<th scope="row">{{ emp.emp_name }}</th>
<td>{{ emp.emp_email }}</td>
<td>{{ emp.emp_contact }}</td>
<td>{{ emp.emp_role }}</td>
<td>{{ emp.emp_salary}}</td>
<td>
<a style="margin-right: 30px;" href="{% url 'edit-employee' emp.id %}">EDITAR</a>
ELIMINAR
</td>
<td>
{%if venue.venue_image%}
{{venue.venue_image.url}}
{%endif%}
</td>
</tr>
{% endfor %}
</tbody>
views.py
I'm expecting the image here:
The issue is with your if condition in your template. You are getting your employees data with for loop and using variable emp not venue. Use this if condition and your image url will be displayed
{% if emp.venue_image %}
{{emp.venue_image.url}}
{% endif %}
If you want to display the image you need to use image tag like this
{% if emp.venue_image %}
<img src="{{emp.venue_image.url}}">
{% endif %}

Django for loop from one DB table

I'm working on a livescore app and can't get matches within leagues in the table, nested for loop is empty.
I only get listed leagues and I would like to have inside the leagues all the matches that belong to those leagues
-Leaugue
match
match
-League
match
match
My DB
Models:
class basic_scores(models.Model):
time_status = models.CharField(max_length=5)
time_minute = models.CharField(max_length=5)
localteam_data_name = models.CharField(max_length=255)
visitorteam_data_name = models.CharField(max_length=255)
scores_localteam_score = models.CharField(max_length=15)
scores_visitorteam_score = models.CharField(max_length=15)
country_name = models.CharField(null=True, max_length=255)
league_name = models.CharField(null=True, max_length=255
View:
def league(request):
#live_list = football_nows.objects.all()
live_list = basic_scores.objects.all()
return render(request, 'league.html',
{'live_list': live_list})
league.html:
<h1>Live</h1>
{% for league in live_list %}
<center>
<td>{{ league.league_name }}</td>
{% for live in league %}
<td>{{ live.time_minute }}</td>
<td>{{ live.localteam_data_name }}</td>
<td>{{ live.scores_localteam_score }} : {{ live.scores_visitorteam_score }}</td>
<td>{{ live.visitorteam_data_name }}</td>
{% endfor %}
</center>
{# This is a comment. #}
{% endfor %}
Browser result:
#Ronnin you need to modify your view and create context correctly to achieve your result.
Lets take it step by step:
Problem in your code. league is not a list or iterator or any kind. It is a single record.
{% for league in live_list %}
<center>
<td>{{ league.league_name }}</td>
{% for live in league %} // this is wrong
<td>{{ live.time_minute }}</td>
<td>{{ live.localteam_data_name }}</td>
<td>{{ live.scores_localteam_score }} : {{ live.scores_visitorteam_score }}</td>
<td>{{ live.visitorteam_data_name }}</td>
{% endfor %}
Make your view to have right context.
def league(request):
#live_list = football_nows.objects.all()
live_list_obj = basic_scores.objects.all()
live_list = {}
for live in live_list_obj:
if not live.league_name in live_list:
live_list[live.league_name] = [live]
else:
live_list[live.league_name].append(live)
return render(request, 'league.html',
{'live_list': live_list})
Here is the html for the view
{% for league_name, league_details in live_list.items %}
<center>
<td>{{ league_name }}</td>
{% for live in league_details %}
<td>{{ live.time_minute }}</td>
<td>{{ live.localteam_data_name }}</td>
<td>{{ live.scores_localteam_score }} : {{ live.scores_visitorteam_score }}</td>
<td>{{ live.visitorteam_data_name }}</td>
{% endfor %}

How to filter data displayed in a table in django?

I have a project where when a user enters a vehicle no, the database is filtered and a table containing that vehicle no and the information corresponding to is displayed. I further want to filter this displayed table, eg: if the user chooses to see quantity greater than 18kl, then the matching vehicle number with quantity greater than 18 is displayed. Also I want to hide the columns selected by the users as there are many columns. Can someone tell me how to do this in django, or suggest some better ways. (I am providing only the related code snippet.)
forms.py
class VehicleSearch(forms.Form):
vehicl[![enter image description here][1]][1]e_no = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}), required=False)
#filter form
class Filter(forms.Form):
capacity_grp = forms.ChoiceField(label='Show only', widget=forms.RadioSelect,
choices=[('abv', '>18 kl'), ('blw', '<18 kl')], required=False)
views.py
def search(request):
form_1 = forms.VehicleSearch()
if request.method == 'POST' and 'btnform1' in request.POST:
form_1 = forms.VehicleSearch(request.POST)
if form_1.is_valid():
vehicle_no = form_1.cleaned_data['vehicle_no']
transport = models.Transport.objects.filter(vehicle=vehicle_no)
my_dict.update({'transport': transport})
return render(request, 'search.html', my_dict)
search.html
/Vehicle form/
<form id="f1" method="POST">
{% csrf_token %}
{{form_1.as_p}}
<p style="padding: 10px;"><button class="myButton" name="btnform1">Search</button></p>
</form>
/*Table display*/
<div class="submain">
{% if transport %}
<table id="transportation">
<thead>
<th>Vehicle</th>
<th>Carrier</th>
<th>Location No</th>
<th>MCMU</th>
<th>Location</th>
<th>Customer Code</th>
<th>Zone</th>
<th>Quantity</th>
<th>RTKM</th>
<th>KL* KM</th>
<th>Amount</th>
<th>Load</th>
<th>Capacity</th>
<th>Rate</th>
<th>Cost</th>
</thead>
{% for i in transport %}
<tr class="item">
<td>{{ i.vehicle }}</td>
<td>{{ i.carrier }}</td>
<td>{{ i.location_no }}</td>
<td>{{ i.mcmu }}</td>
<td>{{ i.location }}</td>
<td>{{ i.customer_code }}</td>
<td>{{ i.zone }}</td>
<td>{{ i.quantity }}</td>
<td>{{ i.rtkm }}</td>
<td>{{ i.klkm }}</td>
<td>{{ i.amount }}</td>
<td>{{ i.load }}</td>
<td>{{ i.capacity }}</td>
<td>{{ i.rate }}</td>
<td>{{ i.cost }}</td>
</tr>
{% endfor %}
</table>
</div>
In the table display you can add a loop with the name's field, something like that:
View:
def search(request):
form_1 = forms.VehicleSearch()
if request.method == 'POST' and 'btnform1' in request.POST:
form_1 = forms.VehicleSearch(request.POST)
columns = request.POST.getlist('filter_hide_columns')
if form_1.is_valid():
vehicle_no = form_1.cleaned_data['vehicle_no']
transport = models.Transport.objects.filter(vehicle=vehicle_no)
my_dict.update({'transport': transport}, {'columns': columns})
return render(request, 'search.html', my_dict)
TemplateTag
def lookup(model, attr):
if hasattr(model, attr):
return getattr(model, attr)
else:
return None
refer https://docs.djangoproject.com/en/2.2/howto/custom-template-tags/
Template:
{% if transport %}
<table id="transportation">
<thead>
<tr>
{% for field in columns %}
<th>{{ field.name }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for t in transport %}
<tr>
{% for field in columns %}
<td>{{ t|lookup:field.name }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
Please refer https://docs.djangoproject.com/en/2.2/topics/forms/#looping-over-the-form-s-fields

Django Master/Detail Template

I have a two classes that define two models
class Master(models.Model):
date = models.DateTimeField()
status = models.CharField(default = 'R')
class Detail(models.Model):
name = models.TextField()
from = models.ForeignKey(Master)
The view:
def list_view(request):
masters = master.objects.filter()
context = {'masters': masters}
return render_to_response('list.html', context, context_instance = RequestContext(request))
The template:
{% for master in masters %}
<tr>
<td>{{ master.date }}</td>
<td>{{ master.status }}</td>
<td>{# THIS #}</td>
</tr>
{% endfor %}
I want to show detail names in {# THIS #} section, but I don't know how to modify the View for that. How can I access to details for the master in template?
You can do something like this to get the names
{% for master in masters %}
<tr>
<td>{{ master.date }}</td>
<td>{{ master.status }}</td>
<td>
{% for detail in master.detail_set.all %}
{{detail.name}}<br/>
{% endfor %}
</td>
</tr>
{% endfor %}

Grouping models in template

I have two related models:
class Package(models.Model):
package_name = models.CharField(max_length=64)
ptype = models.CharField(max_length=16)
class Extra(models.Model):
package = models.ForeignKey(Package, related_name='package')
data = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
information = models.CharField(max_length=1024, blank=True)
view.py:
def show_package(request):
list = get_list_or_404(Package, ptype='sometype')
return render(request, 'table.html', {'list': list})
and template:
{% for row in list %}
<table class="provider_list">
<tr>
<td>{{ row.package_name}}</td>
<td>{{ row.ptype }}</td>
</tr>
</table>
{% endfor %}
How can I add an additional table (from Extra model) next to the prelated table?
Like:
<table>
{% for extra_row in extra_list %}
<tr>
<td>{{ extra_row.data }}</td>
<td>{{ extra_row.information }}</td>
</tr>
{% endfor %}
</table>
Thanks.
try this:
{% for package in list %}
<table class="provider_list">
<tr>
<td>{{ package.package_name}}</td>
<td>{{ package.ptype }}</td>
<td>
<!-- fetch the related data -->
<table>
{% for extra in package.extra_set.all %}
<tr>
<td>{{ extra.data }}</td>
<td>{{ extra.information }}</td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
{% endfor %}
You show modify your Extra related_name on package ForeignKey.
models.py
class Extra(models.Model):
extra = models.ForeignKey(Package,related_name='extra_related_name') #default for related_name would be 'extra_set'
You can access all extra fields via:
extras = list.extra_related_name.all()
Let's imagine you have only one extra existing on every Package model
views.py
def show_package(request):
list = get_list_or_404(Package, ptype='sometype')
list.extra = list.extra_related_name.all()[0]
return render(request, 'table.html', {'list': list})
template
{% for row in list %}
<table class="provider_list">
<tr>
<td>{{ row.package_name}}</td>
<td>{{ row.ptype }}</td>
<td>{{ row.extra.data }}</td>
<td>{{ row.extra.information }}</td>
</tr>
</table>
{% endfor %}
If you are sure that there is at most one extra per package you should look at OneToOneField for easier access. If you are unsure, stick to ForeignKey and add checks in the view to check that you are accessing valid data.