Reputation: 127
I'm trying to develop an application in django. I have a general Publication
table that may or may be not linked to a Project
model.
Here is some code :
class Project(models.Model):
title = models.CharField(max_length=254)
abstract = models.CharField(max_length=254)
link = models.URLField()
def __str__(self):
return self.title
class Publication(models.Model):
id = models.IntegerField(primary_key=True)
title = models.CharField(max_length=254)
authors_string = models.CharField(max_length=254, default='')
project = models.ForeignKey(Project, on_delete=models.DO_NOTHING, blank=True, null=True)
def __str__(self):
return self.title
Now the problem is that I'm trying to display this reference in the template. How can I do that? publication.project.title seems not to work. In general publication seems not to have a project field
{% for p in projects %}
<option value="">{{ p.title }}</option>
{% if p.projects.id %}
<option>{{ p.title }}</option>
{% endif %}
{% endfor %}
What am I missing?
@login_required
def profile(request, initial_page=1):
# Get query params
offset = (initial_page-1) * 10
limit = offset + 10
# Handle default GET request
current_user = request.user
pending_publications = Publication.objects.filter(authors=current_user).order_by('-year')
number_of_pending_publications = Publication.objects.filter(authors=current_user).count()
number_of_pending_pages = int(number_of_pending_publications/10) + 1
confirmed_publications = Publication.objects.filter(authors2=current_user).order_by('-year')
number_of_confirmed_publications = Publication.objects.filter(authors2=current_user).count()
number_of_confirmed_pages = int(number_of_confirmed_publications/10) + 1
projects = Project.objects.all()
if (number_of_confirmed_publications % 10) == 0:
number_of_confirmed_pages -=1
if (number_of_pending_publications % 10) == 0:
number_of_pending_pages -=1
# Set up form defaults
default_form_values = {
"first_name" : request.user.first_name,
"last_name" : request.user.last_name,
"email" : request.user.email,
"organization" : request.user.organization,
"bio" : request.user.bio,
}
# Set up context variables for html
context = {
'form': UpdateProfileForm(initial = default_form_values),
'projects' : projects,
'confirmed_publications' : confirmed_publications[offset:limit],
'number_of_confirmed_publications' : number_of_confirmed_publications,
'number_of_confirmed_pages' : number_of_confirmed_pages,
'pending_publications' : pending_publications[offset:limit],
'number_of_pending_publications' : number_of_pending_publications,
'number_of_pending_pages' : number_of_pending_pages,
'initial_pending_page' : initial_page,
'initial_confirmed_page' : 1,
}
# Render page
return render(request, 'main/publication.html', context)
Upvotes: 1
Views: 3793
Reputation: 2212
You are handling a 1 -> n relationship. In order to access the properties of your Publication
instances from a Project
instance you either need to call yourmodel_set
or provide a related name.
1. Using _set
Supposing you have a Project
instance in your view and would like to iterate over all related Publications this would be e.g
for pub in project.publication_set.all():
print(pub.title)
In a template using the django template language this would be (using your template):
{% for p in projects %}
{{ p.title }}
{% for pub in p.publication_set.all %}
{{ pub.title }}
{% endfor %}
{% endfor %}
2. Using a related name
If you do not like the _set thing you can add a related name and use this to access the related objects.
In your models:
class Publication(models.Model):
id = models.IntegerField(primary_key=True)
title = models.CharField(max_length=254)
authors_string = models.CharField(max_length=254, default='')
project = models.ForeignKey(Project, on_delete=models.DO_NOTHING, blank=True, null=True, related_name='publications')
def __str__(self):
return self.title
and then in your template
{% for p in projects %}
{{ p.title }}
{% for pub in p.publications.all %}
{{ pub.title }}
{% endfor %}
{% endfor %}
If you want to access a Project from a Publication
, the syntax you stated is correct, e.g:
pub.project.title
Upvotes: 4