How can i query a Primary key objects in django 2 template - django

after querying my database, my template doesn't display anything. Please find attached my model, url, templates
MODEL
class ScrumyUser(models.Model):
userRole = (
('O', 'Owner'),
('A', 'Admin'),
('Q', 'Quality Analyst'),
('D', 'Developer'),
)
fullname = models.CharField(max_length=100)
role = models.CharField(max_length=1, choices=userRole)
class GoalStatus(models.Model):
goalStatus = (
('P', 'Pending'),
('V', 'Verified'),
('D', 'Done'),
)
status = models.CharField(max_length=1, choices=goalStatus)
class ScrumyGoals(models.Model):
goalType = (
('WG', 'Weekly Goal'),
('DT', 'Daily Task'),
)
user_id = models.ForeignKey(ScrumyUser, on_delete=models.CASCADE)
status_id = models.ForeignKey(GoalStatus, on_delete=models.CASCADE)
goal_type = models.CharField(max_length=2, choices=goalType)
goal_description = models.TextField()
date_created = models.DateTimeField('dateCreated')
date_updated = models.DateTimeField(null=True, blank=True)
VIEWS
from django.views import generic
from .models import ScrumyGoals, ScrumyUser, GoalStatus
class IndexView(generic.ListView):
template_name = 'greyscrumy/index.html'
context_object_name = 'goals'
def get_queryset(self):
return ScrumyGoals.objects.all()
TEMPLATE INDEX
THIS TEMPLATE DOESN'T DISPLAY ANY DATA ON THE BROWSER
{% if goals %}
<h1>{{ object_list.fullname }}</h1>
<ul>
{% for goal in goals.scrumygoals_set.all %}
<li>{{ goal.goal_type }}</li>
{% endfor %}
</ul>
{% else %}
<p>No goals are available.</p>
{% endif %}
THE SECOND DISPLAYS BUT I DON'T KNOW HOW TO ACCESS SCRUMYUSER AND GOALSTATUS
PLEASE I WOULD REALLY LOVE TO UNDERSTAND THIS, I HAVE MADE SEARCHES ON GOOGLE SINCE YESTERDAY AND COULDN'T FIND ANYTHING
{% for goal in goals %}
{% for innergoal in goals %}
{{ innergoal.id }} {{ innergoal.goal_description }}
{% endfor %}
{% endfor %}

Like this:
{% for goal in goals %}
<h1>{{ goal.user_id.fullname }}</h1>
<p>{{ goal.goal_type }}</p>
<p>{{ goal.goal_description }}</p>
<p>{{ goal.date_created }}</p>
<p>{{ goal.date_updated }}</p>
<p>{{ goal.user_id.role }}</p>
<p>{{ goal.status_id.status }}</p>
{% endfor %}

Related

Django - Problem with DB query using foreign key

I'm using Django for a Web app and I have the following data model:
class classi(models.Model):
nome = models.TextField(null=True)
class Meta:
db_table = 'classi'
class users(models.Model):
name = models.TextField(null=True)
email = models.TextField(null=True)
password = models.TextField(null=True)
classe = models.ForeignKey(classi, db_column='classe', on_delete=models.CASCADE, null=True)
class Meta:
db_table = 'users'
class smartphone(models.Model):
marca = models.TextField(null=True)
modello = models.TextField(null=True)
possessore = models.ForeignKey(users, db_column='possessore', on_delete=models.CASCADE, null=True)
class Meta:
db_table = 'smartphone'
My goal is to show, on an HTML page, all classi, and for each classi all users and for each user all smartphone.
How can I implement my view.py and my html file?
The only solution that I found is to scan all table with a for loop and, through a condition, select the row using foreign key:
{% for c in classi %}
<p>{{ c.nome }}</p>
{% for u in users %}
{% if u.classe == c %}
<p>{{ u.name }}, {{ u.email }}, {{ u.password }}</p>
{% for s in smartphone %}
{% if s.possessore == u %}<p>{{ s.marca }}, {{ s.modello }}</p> {% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
Is there a better solution?
You could use backwards relations, which will only have items that have a connection
The general format is obj.{model}_set but you can also set it to something different in the models.py with the related_name attr in the ForeignKey field
{% for c in classi %}
<p>{{ c.nome }}</p>
{% for u in c.users_set.all %}
<p>{{ u.name }}, {{ u.email }}, {{ u.password }}</p>
{% for s in u.smartphone_set.all %}
<p>{{ s.marca }}, {{ s.modello }}</p>
{% endfor %}
{% endfor %}
{% endfor %}
Or, and this is probably cleaner:
Go the reverse way by looping through the smartphones in the top and just order smartphones by nome in the view with smartphoneList = smartphone.objects.all().order_by('possessore__classe__nome') so they are grouped together
{% for s in smartphoneList %}
<p>{{ s.possessore.classe.nome }}</p>
<p>{{ s.possessore.name }}, {{ s.possessore.email }}, {{ s.possessore.password }}</p>
<p>{{ s.marca }}, {{ s.modello }}</p>
{% endfor %}
Note after writing this I noticed #Lucas Grugru as already posted the reverse relations way.. From my testing it doesn't require pre-fetching, but it's probably a good idea to do that (I also have no idea). I'm still posting this because I think looping through smartphones might be a cleaner way of doing it
You can use *prefetch_related for prefetching related object from foreign key. More information: https://docs.djangoproject.com/fr/4.1/ref/models/querysets/#prefetch-related
The view:
def view(request):
classe = Classi.objects.all().prefetch_related("users_set").prefetch_related("users_set__smartphone_set")
context = {}
context["classe"] =) classe
return render(request, 'template.html', context)
And the html:
{% for c in classe %}
<p>{{ c.nome }}</p>
{% for u in c.users_set.all %}
<p>{{ u.name }}, {{ u.email }}, {{ u.password }}</p>
{% for s in u.smartphone_set.all %}
<p>{{ s.marca }}, {{ s.modello }}</p>
{% endfor %}
{% endfor %}
{% endfor %}

Django - how to get all the users in team when using a costumised user model

I am new to django and have a question: I created a CustomUser model within a users app.
I tried
from users.models import CustomUser, Team
team1= Team.objects.first()
users_team1= team1.user.objects.all()
and it doesnt get me the list of users in this Team
class CustomUser(AbstractUser):
bio= models.CharField(max_length=300, null= True, blank=True)
class Team (models.Model):
title = models.CharField(max_length=200)
user= models.ManyToManyField(get_user_model())
date_created= models.DateTimeField(auto_now_add=True, blank=True, null=True)
date_updated= models.DateTimeField(auto_now=True,blank=True, null=True )
def __str__(self):
return self.title
def get_absolute_url(self): # new
return reverse('team_detail', args=[str(self.pk)])
I want created a HTML page
{% extends '_base.html' %}
{% block title %}{{ object.title }}{% endblock title %}
{% block content %}
<div class="team-detail">
<h2>{{ team.title }}</h2>
<p>Team tile : {{ team.title }}</p>
<p>user: {{ team.user }}</p>
</div>
{% endblock content %}
how can i show all the users in a specific Team?
Thanks in advance.
You should do:
from users.models import CustomUser, Team
team1= Team.objects.first()
# lets pass team1 to your template
return render(request, 'template/name.html', {'team': team1})
Your template should be sthg like:
{% extends '_base.html' %}
{% block title %}{{ object.title }}{% endblock title %}
{% block content %}
<div class="team-detail">
<h2>{{ team.title }}</h2>
<p>Team tile : {{ team.title }}</p>
{% for user in team.user.all %}
<p>user: {{ user }}</p>
{% endfor %}
</div>
{% endblock content %}

combining two or more querysets from different models in django

Main model:
class MainCategory(models.Model):
title = models.CharField(max_length=120, unique=True)
App#1:
class Category(models.Model):
title = models.CharField(max_length=120, unique=True)
main_category = models.ForeignKey(MainCategory, default=1, related_name='car_category')
App#2:
class Category(models.Model):
title = models.CharField(max_length=120, unique=True)
main_category = models.ForeignKey(MainCategory, default=1, related_name='classifieds_category')
on home page I want a combined list of both category list items as follows.
{% for object in main_cat_list %}
{{ object.title }}
{% for item in object.car_category %}
{{ item.title }}
{% endfor %}
{% endfor %}
How I can insert classifieds category also inside this list?
If you merely want to also display the classified_category as you have the car_category.
{% for object in main_cat_list %}
{{ object.title }}
{% for item in object.car_category %}
{{ item.title }}
{% endfor %}
{% for item in object.classified_category %}
{{ item.title }}
{% endfor %}
{% endfor %}

MPTT multiple parents breadcrumbs

Let's say I have a simple model set:
class Category(MPTTModel):
name = CharField(max_length=50)
parent = TreeForeignKey(
'self',
null=True,
blank=True,
related_name='children',
db_index=True
)
class Record(Model):
name = CharField(max_length=50)
category = TreeManyToManyField(SectionArt)
And let's imagine I have a Record that belongs to 3 different categories. How do I make breadcrumbs track from which category I opened my record?
You can track where user came from with request.META['HTTP_REFERER']
views.py
def get_context_data(self, **kwargs):
c = super(RecordDetail, self).get_context_data(**kwargs)
if 'HTTP_REFERER' in self.request.META:
referer = self.request.META['HTTP_REFERER'].split('/')[-2]
c['categories'] = [models.Category.objects.get(slug=referer)]
else:
c['categories'] = self.object.categories.all()
return c
template.html
<ul class="breadcrumbs">
<li>{{ sections.home.title }}</li>
{% if categories %}
{% with category=categories.0 %}
{% for obj in category.get_ancestors %}
<li>{{ obj.title }}</li>
{% endfor %}
<li>{{ category.title }}</li>
{% endwith %}
{% endif %}
<li class="current">{{ object.short_title }}</li>
</ul>
Source

ForeignKey. How to get data?

class Property(models.Model):
title = models.CharField(max_length=255)
class CurrentPrice(models.Model):
current = models.ForeignKey(Current)
prop = models.ForeignKey(Property)
price = models.DecimalField(max_digits=5, decimal_places=2)
class Current(models.Model):
name = models.CharField(max_length=20)
views.py:
...
p = Property.objects.all()
return render_to_response('index.html',{'p':p},context_instance=RequestContext(request))
How to get price of Property and display it in my template?
template:
{% for item in p %}
{{ item.title }}
{{ item.price }} # ???
{% endfor %}
I'm not sure what is your purpose/design of models, which doesn't look appropriate from what you have shown.
You will have many CurrentPrice per Property object, so in template you can do is
{% for item in p %}
{{ item.title }}
{% for cp in item.currentprice_set.all %}
{{ cp.price }}
{% endfor %}
{% endfor %}
If Property can have multiple CurrentPrice objects (what is by default):
{% for item in p %}
{{ item.title }}
{% for current_price in item.currentprice_set.all %}
{{ current_price.price }}
{% endofor %}
{% endfor %}
If only one (but in that case it is better to use o2o field instead of the FK fiel else it is up on you to prevent multiple CurrentPrice records pointing to the same Property):
{% for item in p %}
{{ item.title }}
{{ item.currentprice_set.get.price }}
{% endfor %}
I think what you're trying to do is something like that below.
class Property(models.Model):
title = models.CharField(max_length=255)
#property
def current_price(self):
# The current price is the last price that was given.
if self.pricing_history.count() > 0:
return self.pricing_history.order_by('-when')[0].amount
return None
class Price(models.Model):
prop = models.ForeignKey(Property, related_name='pricing_history')
amount = models.DecimalField(max_digits=5, decimal_places=2)
when = models.DateTimeField(auto_now_add=True)
example in template:
{% for item in p %}
{{ item.title }}
{{ item.current_price }}
{% endfor %}