Django foreignkey relationships in templates - python

I've seen some examples of how to do this on SO but none of them have guided me towards the glory I so desire.
Here are the fields I'm working with:
models.py
class ServerFunctions(models.Model):
server_function = models.CharField(max_length=12)
class Meta:
verbose_name_plural = "Server Function"
def __unicode__(self):
return self.server_function
class Inventory(models.Model):
server_function = models.ForeignKey(ServerFunctions, null=False, blank=False)
views.py
def show_details(request, host_id=1):
host_info = Inventory.objects.filter(id=host_id).values()
return render_to_response('templates/details.html', {'host_info': host_info})
templates/details.html
This gives me the column value from the Inventory table (3) like it should
{{ info.server_function_id }}
This gives me no output at all.
{% for func in info.serverfunctions_set.all %}
{{ func.server_function }}
{% endfor %}
I'm stuck, nothing I've tried seems to work. Thanks for reading.

You are using info.serverfunction_set.all in your template which would be correct if you were traversing a reverse relationship (i.e. you had a ServerFunction and wanted all the related Inventory items). But you aren't, you have a simple forward relationship between Inventory and a ServerFunction:
{% for info in host_info %}
{{ func.server_function.server_function }}
{% endfor %}

Related

Reverse related object lookup ( _set )is not accessing objects

I am Building a BlogApp and I stuck on a Problem. I am trying to access two model objects but Failed many times.
models.py
class Topic(models.Model):
topic_no = models.CharField(max_length=100,default='')
topic_title = models.CharField(max_length=200,default='')
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(Profile,on_delete=models.CASCADE,null=True)
def __str__(self):
return self.dairy_title
class Entry(models.Model):
topic = models.ForeignKey(Topic, on_delete=models.CASCADE,default='',related_name='topic')
date_added = models.DateTimeField(auto_now_add=True,null=True)
updated = models.DateTimeField(auto_now=True)
note = models.TextField()
def __str__(self):
return str(self.topic)
views.py
def show_entry(request):
showd = Entry.objects.all()
context = {'showd':showd}
return render(request ,'mains/showd.html', context)
showd.html
{% for post in topic.journel_set.all %}
{{ post.topic_title }}
{{ post.note }}
{% endfor %}
The Problem
I am trying to access both model's Objects in showd.html.
What have i tried
I saw tons of Answers like :- This This and Many More answers about reverse related object lookup. BUT nothing is worked for me.
I don't know am i doing wrong in this.
Any help would be Appreciated.
Thank You in Advance.
Entry has ForeignKey towards Topic it is not reverse accessor so Entry has only one Topic
So you could for instance do
{% for entry in showd %}
{{ entry.topic.topic_title }}
{{ entry.note }}
{% endfor %}

Django: How to query based on a ForiegnKey and display related data for each ForeignKey?

I am brand new to Django and to programming and I'm trying to make a page that will display the Workout with all the associated Exercises listed under each work out.
For example:
Chest
Chest Press
Incline Press
Flat Flyes
Shoulders
Shoudler Press
Arnold Press
Back/Legs
Wide Grip Pull Up
Neutral Grip Pull Up
Bent Over Row
Here is my code:
models.py
class Workout(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class Exercise(models.Model):
workout = models.ForeignKey(Workout, on_delete=models.CASCADE, related_name='workouts')
title = models.CharField(max_length=100)
weight = models.DecimalField(decimal_places=0, max_digits=10000)
date_posted = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
views.py
def home(request):
context = {
'workouts': Workout.objects.all()
}
return render(request, 'workouts/home.html', context)
def workout(request):
context = {
'workouts': Workout.objects.all(),
'exercises': Exercise.objects.all()
}
return render(request, 'workouts/workout.html', context)
workout.html
{% extends 'workouts/base.html' %}
{% block content %}
{% for workout in workouts %}
<h1>{{ workout.title }}</h1>
{% for exercise in exercises %}
<h3>{{ exercise.title }}</h3>
<p>{{ exercise.weight }}</p>
{% endfor %}
{% endfor %}
{% endblock content %}
In my view.py I have it set to Exercise.objects.all() which just displays all of the exercises under each Workout title, I can figure out how to get only the exercises that are associated with the Workout.
Like I said I am brand new to all of this and I'd appreciate any help! Thanks!
You can define property to Workout model to retrieve exercises related to the instance. Just add a new method with property decorator to retrieve Exercises related with that Workout.
class Workout(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
#property
def exercises(self):
return self.workouts.all()
Then you can use exercises in your html file like:
{% extends 'workouts/base.html' %}
{% block content %}
{% for workout in workouts %}
<h1>{{ workout.title }}</h1>
{% for exercise in workout.exercises %}
<h3>{{ exercise.title }}</h3>
<p>{{ exercise.weight }}</p>
{% endfor %}
{% endfor %}
{% endblock content %}
Another approach may be grouping Exercises with workouts in your view and pass them to template. For more information, you can check regroup
When you define FK relationship between two models, Django adds a manager to target model to query related objects. When you use this manager, you basicly run a query something like Exercise.objects.filter(workout_id=workout_instance_id). This is a queryset, so you can join with features of queryset features like filter, first and extra. You can use a plenty of queryset features on related objects. This is basicly the power of Django ORM mechanism. You can find a bit more in documentation if you need to.

Filter on many-to-one model

I want to be able assign users vehicle registrations, and when the user logs into the website their home page should have a list of vehicle regs they own.
However I cannot get the model class to filter on the foreign key.
views.py
#login_required
def home(request):
# This is the basic user landing Page
veh_list = Vehicle.objects.filter(UserProfile.user)
return render(request, 'portal/home.html', {"veh_list": veh_list})
model.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserProfile(models.Model):
# This line is required. Links UserProfile to a User model instance.
user = models.OneToOneField(User)
# The additional attributes we wish to include.
compName = models.CharField(max_length = 20)
milkco = models.IntegerField()
# Override the __unicode__() method to return out something meaningful!
def __unicode__(self):
return self.user.username
class Vehicle(models.Model):
vehid = models.CharField(max_length = 10)
company = models.ForeignKey(UserProfile, default = 1)
class Meta:
db_table = "vehicle"
def __unicode__(self):
return self.vehid
home.html
<!DOCTYPE html>
{% extends 'portal/base.html' %}
{% block title %}{{user.first_name }} {{ user.last_name }} Portal{% endblock %}
{% block content %}
<p>This is the home Page</p>
{% if user.is_authenticated %}
<h4>Optiload says... hello {{ user.first_name }} {{ user.last_name }}!</h4>
{% endif %}
{% for veh in veh_list %}
{{ veh}}
{% endfor %}
{% if user.is_authenticated %}
Logout<br/>
{% endif %}
{% endblock %}
Could someone help me with where I'm going wrong?
Thanks
Django offers a powerful and intuitive way to “follow” relationships in lookups, taking care of the SQL JOINs for you automatically, behind the scenes. To span a relationship, just use the field name of related fields across models, separated by double underscores, until you get to the field you want.
So your query should look like
veh_list = Vehicle.objects.filter(company__user=request.user)
Reference
You cannot make queries with unnamed arguments:
Vehicle.objects.filter(UserProfile.user)
In this case you want:
Vehicle.objects.filter(company=[your user])

How to order by a field from the `through` table for a M2M relationship in Django?

I have two models — Note and Pinboard — with a many to many relationship in a Django app. Those two models are related trough another model — Pin — so I can store additional information about the relationship.
I want to show the related Note instances in the DetailView for Pinboard. That's not the problem. But I want to prefetch the notes and also order them on the position field from the through table.
Any hints on how to archive this (prefetch + ordering on third table)?
Example
This is what I have so far… it works in the sense, that I don't have to query for each entry, but I found no way to order the Note instances by their position without more queries for each instance.
Models
from django.db import models
class Note(models.Model):
title = models.CharField(max_lenght=200)
content = models.TextField()
class Pinboard(models.Model):
title = models.CharField(max_lenght=200)
notes = models.ManyToManyField(
Note, blank=True, related_name='pinboards', through='Pin'
)
class Pin(models.Model):
class Meta:
ordering = ['position', ]
get_latest_by = 'position'
pinboard = models.ForeignKey(Pinboard, related_name='note_pins')
note = models.ForeignKey(Note, related_name='pinboard_pins')
position = models.PositiveSmallIntegerField(default=0)
View
from django.views.generic import DetailView
class PinboardDetailView(DetailView):
model = Pinboard
queryset = Pinboard.objects.prefetch_related('notes')
Template
{% extends 'base.html' %}
{% block content %}
<h1>{{ pinboard.title }}</h1>
{% if pinboard.notes.all.exists %}
<ol>
{% for note in pinboard.notes %}
<li>{{ note.title }}</li>
{% endfor %}
</ol>
{% else %}
<p>Nothing here yet…</p>
{% endif %}
{% endblock content %}
I suggest you use a Prefetch object.
class PinboardDetailView(DetailView):
model = Pinboard
queryset = Pinboard.objects.prefetch_related(
Prefetch(
'notes',
Note.objects.order_by('pinboard_pins__position'),
)
)
By the way, you don't need to use prefetch_related at all on a DetailView as it will result in the same number of queries.
Plus, since you're already fetching the pinboard.notes I suggest you use {% if pinboard.notes.all %} instead of {% if pinboard.notes.all.exists %}.

Querying Many to many fields in django template

This may not be relevant but just wanted to ask,
IF an object is passed from views to template and in the template will i be able to query many to many fields
Models code:
class Info(models.Model):
xls_answer = models.TextField(null=True,blank=True)
class Upload(models.Model):
access = models.IntegerField()
info = models.ManyToManyField(Info)
time = models.CharField(max_length=8, null=True,blank=True)
error_flag = models.IntegerField()
def __unicode__(self):
return self.access
Views:
// obj_Arr contains all the objects of upload
for objs in obj_Arr:
logging.debug(objs.access)
logging.debug(objs.time)
return render_to_response('upload/new_index.html', {'obj_arr': obj_Arr , 'load_flag' : 2})
In template is it possible to decode the many to many field since we are passing the object
Thanks..
In general, you can follow anything that's an attribute or a method call with no arguments through pathing in the django template system.
For the view code above, something like
{% for objs in obj_arr %}
{% for answer in objs.answers.all %}
{{ answer.someattribute }}
{% endfor %}
{% endfor %}
should do what you're expecting.
(I couldn't quite make out the specifics from your code sample, but hopefully this will illuminate what you can get into through the templates)
It's also possible to register a filter like this:
models.py
class Profile(models.Model):
options=models.ManyToManyField('Option', editable=False)
extra_tags.py
#register.filter
def does_profile_have_option(profile, option_id):
"""Returns non zero value if a profile has the option.
Usage::
{% if user.profile|does_profile_have_option:option.id %}
...
{% endif %}
"""
return profile.options.filter(id=option_id).count()
More info on filters can be found here https://docs.djangoproject.com/en/dev/howto/custom-template-tags/

Categories

Resources