Reputation: 93
Sorry for my English level and my model is not good.
Now, i'm stuck showing value in templates.
purchaseinfo/models.py
class Status(Models.model):
type = models.CharField(max_length=30)
class PurchaseInfo(models.Model):
purchase_id = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
purchase_name = models.CharField(max_length=30)
.....
type = models.ForeignKey(Status,on_delete=models.PROTECT)
customlogin/views.py
def purchaseHistory(request):
history = PurchaseInfo.objects.filter(purchase_id=request.user).values()
return render(request,'customlogin/purchaseHistory.html',{'history':history})
customlogin/purchaseHistory.html
{% for i in history %}
<tr>
<td>{{i.purchase_name}}</td>
<td>{{i.product_price}}</td>
......
<td>{{i.type}}</td> <---- Here, Only this cannot show
</tr>
{% endfor %}
In templates, Other things work well. But {{i.type}} cannot show.
class Status's values : before deposit, Confirmation of payment and so on.
before deposit is base value. So i want to show base value in templates.
How can show the {{i.type}} in templates?? T.T
Upvotes: 1
Views: 224
Reputation: 476624
The error is due to the fact that you call the QuerySet
with .values()
at the end, and therefore you will obtain a QuerySet
of dictionaries. Foreign keys are not resolved, but you fetch the corresponding primary key.
It is better to use .values()
only when you really need it: when you want to fetch a subset of columns. Normally it is better to fetch model objects, since then the "behavior" you attached to the objects remains the same.
def purchaseHistory(request):
# no .values()
history = PurchaseInfo.objects.filter(purchase_id=request.user)
return render(request,'customlogin/purchaseHistory.html',{'history':history})
Now that we have made a QuerySet
of PurchaseInfo
objects, in the template, i.type
will be Status
object. This will render the Status
object, by calling the str(..)
object. By default this will look like Status object (123)
with 123
You can however access fields from this Status
object in the template as well:
{% for i in history %}
<tr>
<td>{{ i.purchase_name }}</td>
<td>{{ i.product_price }}</td>
......
<td>{{ i.type.type }}</td>
</tr>
{% endfor %}
given the name of the field is type
, so if that field contains as value 'Before deposit'
, it will render that string.
Since we here will fetch the related Status
object for each PurchaseInfo
object in the queryset, it is better to fetch it in one query, like:
def purchaseHistory(request):
# no .values()
history = PurchaseInfo.objects.filter(purchase_id=request.user).select_related('type')
return render(request,'customlogin/purchaseHistory.html',{'history':history})
You might want to override the __str__
method in the Status
class, such that this is the "standard" way of rendering the status, like:
class Status(Models.model):
type = models.CharField(max_length=30)
def __str__(self):
return self.type
In that case {{ i.type }}
in the template will suffice.
Upvotes: 2