Reverse related object lookup ( _set )is not accessing objects - python

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 %}

Related

Django: Problem with Understanding Objects in For Loop

I am a beginner in Django. I am building a Django app, named PhoneReview. It will store reviews related to the latest mobile phone. It will also display phone brands, along with the associated phone models. I have managed to do some protion of the app. Right now, I am a bit confused with a line of code.
I have a code like this in one of my template files:
{% extends 'gamereview/base.html' %}
{% block title%}
Detail
{% endblock %}
{% block content %}
<h3>This is the review for {{game.title}} </h3>
<ul>{% for review_item in game.review_set.all %}
<li>{{ review_item.review }}</li>
{% endfor %}
</ul>
{% endblock %}
I don't understand this portion:
<ul>{% for review_item in game.review_set.all %}
What does this line mean?
Here are the codes in models.py:
from django.db import models
from django.template.defaultfilters import slugify
# Create your models here.
class Tag(models.Model):
label = models.CharField(max_length=20)
def __str__(self):
return self.label
class Game(models.Model):
title = models.CharField(max_length=100)
developer = models.CharField(max_length=100)
platform = models.CharField(max_length=50, default='null')
label_tag = models.ManyToManyField(Tag)
slug = models.SlugField(max_length=150, default='null')
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save(*args, **kwargs)
class Review(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE)
review = models.CharField(max_length=1000)
date = models.DateField(auto_now=True)
slug = models.SlugField(max_length=150, default='null')
def __str__(self):
return self.review
def save(self):
super(Review, self).save()
self.slug = '%i-%s' % (
self.id, slugify(self.game.title)
)
super(Review, self).save()
Here are the codes in views.py:
from django.views import generic
from .models import Game
class GameListView(generic.ListView):
template_name = 'gamereview/gamelist.html'
context_object_name = 'all_games'
def get_queryset(self):
return Game.objects.all()
class ReviewView(generic.DetailView):
model = Game
template_name = 'gamereview/review.html'
Here are the codes in urls.py:
from . import views
from django.urls import path
app_name = 'gamereview'
urlpatterns = [
path('gamereview/', views.GameListView.as_view(), name='gamelist'),
path('gamereview/<slug:slug>/', views.ReviewView.as_view(), name='review'),
]
I am a bit confused by this line: <ul>{% for review_item in game.review_set.all %}. Would you please help me to clarify?
Look at the models; there is a Game class. Apparently you receive an instance of that class in your template under the name game.
The Game class is referenced as a foreign key by Review class. This, due to the way Django ORM works, gives Game class a reverse link .review_set; it contains all review objects that refer to the particular game. Hence game.review_set.
That .review_set attribute is not a list but a DB result set. You can filter it, sort it, etc, but in your case you just fetch all the records from it. Hence game.review_set.all.
Please take some time to read an intro to how Django works, a number of things there cannot be derived from mere common sense.
I'd like to add something that was helpful for me when referencing the related database result set:
In your class, you can specify a "related_name" for the foreign key and use it to reference that result set in your template.
For instance,
class Review(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE, related_name="game_reviews")
And, now you reference this in your template (assuming the context name is all_games):
{% for x in all_games %}
{% all_games.title %} </br>
<ul>{% for review_item in game.game_reviews.all %}
<li>{{ review_item.review }}</li>
{% endfor %}
</ul>
{% endfor %}
Of course, you can further simplify the related_name to just "reviews" and shorten your code that much more. And, it's all very logical when you read it.

How to create a form field for every foreignkey in manytomany relationship in Django

I don't understand how to build a specific form in Django.
First of all here are my models:
class Category(models.Model):
name = models.CharField(max_length=200, unique=True)
class Assessment(models.Model):
name = models.CharField(max_length=200)
pub_date = models.DateTimeField(verbose_name=_('date published'), default=timezone.now)
classgroup = models.ForeignKey(ClassGroup, verbose_name=_('class'), on_delete=models.CASCADE, related_name='+')
category = models.ManyToManyField(Category, through='AssessmentScale', through_fields=('assessment', 'category'),)
total = models.IntegerField()
class AssessmentScale(models.Model):
assessment = models.ForeignKey(Assessment, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
value = models.IntegerField()
I would like to have a form like this html form. Actually, an assessment scale is sub-divided into different categories. So when I create an assessment, I'd like have a form field for each category allowing to add a value via my custom intermediary model AssessmentScale. But I really don't know the Django way to build this form. I read this post, which is similar I think, and someone advised the use of Inline model formsets. But I don't understand how to solve my problem with the latter. Could you help me?
I had no answer from Stackoverflow but a friend of mine solved my problem like this with inline formset:
# forms.py
class AssessmentForm(ModelForm):
class Meta:
model = Assessment
exclude = ('category',)
CategoryAssessmentFormSet = inlineformset_factory(
Assessment,
Assessment.category.through,
fields=['category', 'value'],
can_delete=False,
extra=Category.objects.count(),
max_num=Category.objects.count(),
widgets={'category': Select(attrs={'hidden': 'true'})}
)
in my view, to render the formset:
# views.py
initial = [{'category': category} for category in Category.objects.all()]
formset = CategoryAssessmentFormSet(initial=initial)
Select is hidden but I still want the name of the selected field, in my template:
# template
{{ formset.management_form }}
{% for form in formset %}
<div class="p-2">
{% for value,selected in form.fields.category.choices %}
{% if value == form.category.value %}{{ selected }}{% endif %}
{% endfor %}
{{ form.category }}
</div>
<div>
{{ form.value}}
</div>
{% endfor %}

Displaying a list of table entries in Django

I have a database table that allows you to enter details about a particular person. How can i then list all the entries of that table to show all the people added to the database.
urls.py
url(r'^accounts/loggedin/locations/all/$', 'assessments.views.locations'),
url(r'^accounts/loggedin/locations/get/(?P<location_id>\d+)$', 'assessments.views.location'),
url(r'^accounts/loggedin/locations/create/$', 'assessments.views.create'),
models.py
class People(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
view.py
def people(request):
return render_to_response('dashboard/people.html', {'people': People.objects.all})
people.html
<body>
<h1>People</h1>
{% for p in people %}
<h1>{{ people.first_name }}</h1>
{% endfor %}
</body>
</html>
Two problems:
you should call all() to get the results, note the ():
People.objects.all()
in the template, you should use {{ p.first_name }} instead of {{ people.first_name }} since you are iterating over people variable which is a QuerySet - a list of objects, basically
it is same question with this link
If you had the Question model below,
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField(verbose_name='date published')
Through this code, you can see all entries (or fields, features).
fields = Question._meta.get_fields()
thanks.

Django foreignkey relationships in templates

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 %}

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