Django model cross reference in templatre - django

Ok So my mind is going to mush...
I have 2 models. One is a card location and the other holds card types. I've got a view and template which display's the cards in a specific chassis. What I can't seem to get to work is the foreign key reference. I want to display the CardType.sName in the template.
I'm certain i've just done something stupid ...
Models.py:
class CardLocation(models.Model):
chassis = models.ForeignKey(Chassis)
slot = models.CharField(max_length=20)
slot_sub = models.CharField(max_length=20)
CardType = models.ForeignKey(CardType)
PartNum = models.CharField(max_length=200)
ProdID = models.CharField(max_length=200)
versID = models.CharField(max_length=200)
serialNum = models.CharField(max_length=200)
cleiCode = models.CharField(max_length=200)
lastSeen = models.DateTimeField()
isActive = models.BooleanField(default=0)
def __unicode__(self):
return self.slot
class CardType(models.Model):
sName = models.CharField(max_length=5)
lName = models.CharField(max_length=200)
description = models.CharField(max_length=200)
def __unicode__(self):
return self.sName
views.py
class DetailView(generic.ListView):
model = CardLocation
template_name = 'chassis/detail.html'
context_object_name = 'cardLoc'
def get_queryset(self):
#chassis_id = get_object_or_404(CardLocation, chassis_id__iexact=self.args[0])
chassis_id = self.args[0]
return CardLocation.objects.filter(chassis_id=chassis_id)
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(DetailView, self).get_context_data(**kwargs)
# Add in the
context['chassisQ'] = Chassis.objects.get(id=self.args[0])
#context['CardType'] = CardType.objects.order_by()
return context
detail.html
{% load staticfiles %}
<h2>
<table>
<tr><td>Name:</td><td>{{ chassisQ.name }}<td></tr>
<tr><td>Owner:</td><td>{{ chassisQ.owner }}<td></tr>
<tr><td>ip Adress:</td><td>{{ chassisQ.ipAddr }}<td></tr>
<tr><td>Last updated:</td><td>{{ chassisQ.lastSeen }}<td></tr>
</table>
</h2>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% if cardLoc %}
<table border=1>
<tr><td>slot</td><td>Type</td><td>Part Number</td><td>Product ID/</td><td>Version ID</td><td>Serial Num</td><td>CLEI code</td></tr>
{% for card in cardLoc %}
<tr>
<td align="right">{{ card.slot }}</td>
<td>Type {{ card.cardtype__set.all.sName }} </td> <!-- DISPLAY sName HERE -->
<td>{{ card.PartNum }}</td>
<td align="right">{{ card.ProdID }}/</td>
<td align="left">{{ card.versID }}</td>
<td>{{ card.serialNum }}</td>
<td>{{ card.cleiCode }}</td>
</tr>
{% endfor %}
</table>
{% else %}
<p>No cards are available...</p>
{% endif %}

A Card has numerous CardTypes (as it's a ForeignKey relationship), not just one. You have:
<td>Type {{ card.cardtype__set.all.sName }} </td>
You need to loop through all the CardTypes related to the Card:
{% for card in cardLoc %}
...
{% for cardtype in card.cardtype__set.all %}
<td>Type {{ cardtype.sName }}</td>
{% endfor %}
...
{% endfor %}

Related

For loop in template django with prefetch_related

I got an issue when trying to access values from other models by using prefetch_related
My model:
class testimport(models.Model):
id=models.AutoField(primary_key=True)
so_hd=models.CharField( max_length=50, unique=True)
ten_kh=models.CharField( max_length=500)
tien_dong=models.IntegerField(blank=True, null=True)
created_at=models.DateTimeField(auto_now_add=True)
objects=models.Manager()
def get_absolute_url(self):
return "/chi_tiet_hop_dong/%s/" % self.so_hd
class report(models.Model):
id=models.AutoField(primary_key=True)
so_hd=models.ForeignKey(testimport, on_delete=models.DO_NOTHING, to_field="so_hd")
nhan_vien=models.ForeignKey(Callers, on_delete=models.DO_NOTHING, null=True, blank= True, to_field="admin_id")
noi_dung=models.TextField()
My views:
....
get_contract_detail=testimport.objects.filter(so_hd__in=get_user).order_by("id").prefetch_related().values()
contract=get_contract_detail.filter(so_hd=so_hd).all()
return render(request, "caller_template/contract_detail.html", {"contract":contract,"the_next":the_next,"the_prev":the_prev, "so_hd":so_hd,"form":form,"form1":form1})
If I try to print out the content by values, it is ok:
print(get_contract_detail.filter(so_hd=so_hd).values("so_hd","report__noi_dung"))
In my template:
{% for report in contract %}
{% for content in report.so_hd.all%}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{content.noi_dung}}</td>
</tr>
{% endfor %}
{% endfor %}
There is no content in cells. How can I show the content
Please help
The reason this does not work is because of the use of .values(…) [Django-doc]. Furthermore you did not specify a related_name=… parameter [Django-doc], so that means that you access the reports with .report_set.all():
contract = testimport.objects.filter(
so_hd__in=get_user, so_hd=so_hd
).order_by('id').prefetch_related() # no .values()
context = {
'contract': contract,
'the_next': the_next,
'the_prev': the_prev,
'so_hd': so_hd,
'form': form,
'form1':form1
}
return render(request, 'caller_template/contract_detail.html', context)
and in the template render with .report_set.all:
{% for report in contract %}
{% for content in report.report_set.all %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ content.noi_dung }}</td>
</tr>
{% endfor %}
{% endfor %}

Why data from table is not recieving in django?

When I tried to retrieve data from table it is not showing anything without giving error message.
This is my model
class staff(models.Model):
id = models.AutoField
name = models.CharField(max_length=250)
role = models.CharField(max_length=250)
salary = models.CharField(max_length=250)
address = models.CharField(max_length=250)
number = models.CharField(max_length=250)
date = models.DateField()
This is my views file
def user(request):
staffs = staff.objects.all()
params = {'staff': staffs}
return render(request, "salary/user.html", params)
and this is my template
<td> 02312 </td>
{% for staff in staffs %}
<td>{{ staff.name }} </td>
{% endfor %}
<td> $14,500 </td>
try this
views.py
def user(request):
staffs = staff.objects.all()
return render(request, "salary/user.html", {'staff': staffs})
html
<td> 02312 </td>
{% for staffs in staff %}
<td>{{ staffs.name }} </td>
{% endfor %}
<td> $14,500 </td>

Ordering a filter result in Django

I made a Search results function in view.py:
def search_results(request):
book_list = Book.objects.all()
book_filter = BookFilter(request.GET, queryset=book_list)
book_list = book_filter.qs.order_by('title')
return render(request, 'catalog/search_results.html', {'filter': book_list})
But it seems that the line
book_list = book_filter.qs.order_by('title')
doesn't have any effect on the result. Could someone help?
The BookFilter class looks like:
class BookFilter(django_filters.FilterSet):
Cim = django_filters.CharFilter(field_name="title",
lookup_expr='icontains',
label="Book's title")
Author = django_filters.CharFilter(field_name="Author__first_name",
lookup_expr='icontains',
label="Book's author")
Status = django_filters.CharFilter(field_name="Status",
lookup_expr='icontains',
label="Book's status")
class Meta:
model = Book
fields = '__all__'
The html containing the results looks like this:
{% for book in filter.qs %}
<tr style="background-color:{{ book.BackColor }}">
<td><a style="color: {{ book.ForeColor }}" href="{{ book.get_absolute_url }}">{{ book.title}}</a></td>
<td style="color: {{ book.ForeColor }}">{{ book.Author.last_name }} {{ book.Author.first_name }}</td>
</tr>
{% empty %}
<tr>
<td style="color: #aeb189" colspan="5">No books</td>
</tr>
{% endfor %}
Use OrderingFilter. Add order_by = OrderingFilter(fields=("title",)) to your filter class.

How to Query DB using .object in Django

I have few categories. Say Electronics and Toy. and i have mutiple shops in a mall. A shop is saved with a foreign key(category). Now in the navigation bar.. i want to list stores based on their categories. Thanks in anticipation
models.py
class ShopCategories(models.Model):
category = models.CharField(max_length=50, unique=True,)
def __str__(self):
return self.category
class NewShop(models.Model):
category = models.ForeignKey(ShopCategories)
name = models.CharField(max_length=100, unique=True)
tagline = models.CharField(max_length=50, default='Enter tagline here2')
description = models.TextField(default='enter shop description')
def __str__(self):
return self.name
views.py
def basefile(request):
shop_cat = NewShop.objects.filter(category_id=1)
shop_name = NewShop.objects.filter(name=shop_cat)
return render_to_response('base.html', {'Shopname':shop_name, 'Shopcat':shop_cat})
base.html
{% for category_id in Shopcat %}
<li>{{ Shopname }}</l>
{% endfor %}
To get all store use below query.
shopcat = NewShop.objects.filter(category__category="category name")
base.html
{% for shop in shopcat %}
<li>{{ shop.name }}</l>
{% endfor %}
Try do this:
urls.py
urlpatterns = [
...
url(r'^get_shops_by_category/(?P<id_category>\d+)/$', views.get_shops_by_category, name = "get_shops_by_category"),
]
views.py
def basefile(request):
categories = ShopCategories.objects.all()
shop_name = NewShop.objects.filter(name=shop_cat)
return render_to_response('base.html', {'Shopname':shop_name, 'categories': categories})
def get_shops_by_category(request, **kwargs):
categories = ShopCategories.objects.all()
current_category = ShopCategories.objects.get(id = kwargs['id_category']
shops = NewShop.objects.filter(category = current_category)
return render_to_response('base.html', {'shops': shops, 'categories': categories, 'current_category' current_category})
base.html
...
<select>
{% for category in categories %}
{% if current_category %}
<option value="{{ category.id }}">{{ category.category }}</option>
{% else %}
<option value="{{ category.id }}" onclick="location.href = '{% url 'your_app:your_url' category.id %}'">{{ category.category }}</option>
{% endfor %}
</select>
{% if shops %}
<table>
<thead>
<tr>
<th>Shop name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for shop in shops %}
<tr>
<td>{{ shop.name }}</td>
<td><!-- Buttons or links, ect ... --></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
...
Thanks Guys. I know this isn't the best method but i was able to fix it this way
models.py
class ShopCategories(models.Model):
category = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.category
class NewShop(models.Model):
category = models.ForeignKey(ShopCategories)
name = models.CharField(max_length=100, unique=True)
tagline = models.CharField(max_length=50, default='Enter tagline here2')
description = models.TextField(default='enter shop description')
def __str__(self):
return self.name
views.py
def basefile(request):
cat1 = NewShop.objects.filter(category_id=1)
cat2 = NewShop.objects.filter(category_id=2)
cat3 = NewShop.objects.filter(category_id=3)
cat4 = NewShop.objects.filter(category_id=4)
shop_name1 = ShopCategories.objects.filter(id=1)
shop_name2 = ShopCategories.objects.filter(id=2)
shop_name3 = ShopCategories.objects.filter(id=3)
shop_name4 = ShopCategories.objects.filter(id=4)
return render_to_response('base.html', {'Shop_cat1':cat1, 'Shop_cat2':cat2, 'Shop_cat3':cat3,
'Shop_cat4':cat4,'shop_name1':shop_name1, 'shop_name2':shop_name2,
'shop_name3':shop_name3, 'shop_name4':shop_name4})
base.html
{% for shop_name1 in shop_name1 %}
<li>
<h3> {{ shop_name1 }}</h3>
</li>
{% endfor %}
{% for Shop_cat1 in Shop_cat1 %}
<li>{{ Shop_cat1 }}</li>
{% endfor %}

Display a form and the output on the same page

This code will display the form. I can input data, submit the data and the data then displays along with the previous input data from the mySQL DB table where the dat is written, but when the data displays the input form goes away (all expect the submit button that is). I've come across this subject here, but could never quite find the answer that worked for me.
**`models.py`**
class UnitPool(models.Model):
# rack = models.ForeignKey(Rack)
# platform = models.ForeignKey(Group)
location = models.CharField(max_length=10, choices=LAB, default='Choose', blank=False)
rack = models.CharField(max_length=10, choices=RACKS, default='Choose', blank=False)
platform = models.CharField(max_length=10, choices = PLATFORM, default='Choose',blank=False)
unit_HW_Serial = models.CharField(max_length=20, blank=False, null=False)
unit_SW_Serial = models.CharField(max_length=20, blank=False, null=False)
unit_SKU = models.CharField(max_length=20, blank=False, null=False)
comments = models.CharField(max_length=64, blank=True, null=True, default='')
def __unicode__(self): # __unicode__ on Python 2
return '%s %s %s %s %s %s' % (self.rack,
self.platform,
self.unit_HW_Serial,
self.unit_SW_Serial,
self.unit_SKU,
self.comments)
class UUTForm(ModelForm):
class Meta:
model = UnitPool
widgets = {
'comments': TextInput(attrs={'size': 10}),
}
fields = ['location','rack', 'platform','unit_HW_Serial','unit_SW_Serial','unit_SKU','comments']
**forms.html**
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
<div class='row'>
<div class='col-md-2'>
{% if title %}
<h1 class='{% if title_align_center %}text-align-center{% endif %}'>{{ title }}</h1>
{% endif %}
<form method='POST' action=''>{% csrf_token %}
{{ form|crispy }}
<input class='btn btn-primary' type='submit' value='Add Unit' />
</form>
</div>
</div>
</div>
{% if queryset %}
{% if rack != '' %}
<div class="container">
<div class="row">
<div class='col-md-8 col-md-offset-3'>
<h1>Unit Data Entered</h1>
<table class='table'>
<td><b>Item</b></td>
<td><b>Location</b></td>
<td><b>Rack#</b></td>
<td><b>Platform</b></td>
<td><b>HW SN</b></td>
<td><b>SW SN</b></td>
<td><b>SKU</b></td>
<td><b>Comment</b></td>
{% for instance in queryset %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ instance.location }}</td>
<td>{{ instance.rack }}</td>
<td>{{ instance.platform }}</td>
<td>{{ instance.unit_HW_Serial }}</td>
<td>{{ instance.unit_SW_Serial }}</td>
<td>{{ instance.unit_SKU }}</td>
<td>{{ instance.comments }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
{% endif %}
{% endif %}
{% endblock %}
**views.py**
from django.conf import settings
from django.shortcuts import render
from .models import UnitPool, UUTForm
def labunits(request):
title = 'Enter Info'
form = UUTForm(request.POST or None)
context = {
"title": title,
"form": form
}
if form.is_valid():
instance = form.save(commit=False)
instance.save()
queryset = UnitPool.objects.all().order_by('rack','platform')
context = {
"queryset": queryset
}
return render(request, "labunits/forms.html", context)
You need to pass the form in the context after calling .is_valid() as #Daniel also mentioned.
Since you are not passing the form in the context again after calling the .is_valid() function, the form does not get displayed again in the template.
So, when you are resetting the context, you need to pass the form also.
def labunits(request):
title = 'Enter Info'
form = UUTForm(request.POST or None)
context = {
"title": title,
"form": form
}
if form.is_valid():
instance = form.save(commit=False)
instance.save()
queryset = UnitPool.objects.all().order_by('rack','platform')
context = {
"queryset": queryset,
"form" : form # pass the form in the context
}
return render(request, "labunits/forms.html", context)