Django: Template logic not rendering query data, no errors given either - django

I have a template based view that doesn't seem to be working(or atleast doesnt seem to be working on the page that needs to render it).
Here is the View:
class LocationManager(View):
template_name = "dash/LocationManager.html"
def get(self, request, *args, **kwargs):
try:
user = User.objects.get(username=request.user.username)
locations = user.get_profile().owned_locations
return render(request, self.template_name, {'locations': locations})
except:
return render(request, self.template_name)
Here are the models that have to do with this view:
#in Location models
class Location(models.Model):
region = models.ForeignKey(Region)
manager = models.ForeignKey(User)
name = models.CharField(max_length=255)
street_address = models.TextField(blank=True)
city = models.CharField(max_length=255, blank=True)
zip_code = models.CharField(max_length=20, blank=True)
#in UserProfile models
class UserProfile(models.Model):
user = models.OneToOneField(User)
api_key = models.TextField()
pp_api_key = models.TextField(blank=True)
owned_beacons = models.ManyToManyField(
Beacon,
blank=True,
null=True,
related_name='owned_beacons'
)
owned_locations = models.ManyToManyField(
Location,
blank=True,
null=True,
related_name='owned_locations'
)
def __unicode__(self):
return u'%s' % self.user.username
And finally the template:
{% for location in locations.all %}<tr>
<td>{{location.name}}</td>
<td>{{location.street_address}}</td>
<td>{{location.zip_code}}</td>
<td>{{location.region}}
</tr>
{% endfor %}
Yet the template does not render anything in relation to the form logic(the rest of the template loads fine). No errors are raised either which is why this is making it hard for me to understand why the template logic/view isn't working properly. Any ideas would be really helpful.

Try {% for location in locations %}

Related

Am trying to get individual posts by a particular user. If i click on a particular users i want to get all the posts he has posted Django

Am actually new to programming, so i am just getting a blank page, no errors.
This is my model
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile',
blank=True, null=True)
bio = models.TextField(max_length=500, null=True)
location = models.CharField(max_length=30, null=True)
def __str__(self):
return self.user.username
def get_absolute_url(self):
return reverse('outcome:userprofile-detail', kwargs={'pk': self.pk})
class Post(models.Model):
text = models.TextField(max_length=255)
profile = models.ForeignKey('Profile', null=True, on_delete = models.CASCADE, related_name='create')
overview = models.CharField(max_length=255)
def __str__(self):
return self.text
The view
class Userlist(LoginRequiredMixin, ListView):
model = Profile
template_name = 'outcome/user-list.html'
class UserDetail(LoginRequiredMixin, DetailView):
model = Profile
template_name = 'outcome/userprofile_detail.html'
The template
{% for i in post.profile_set.all %}
**`trying to loop over the post`**
{{i.text}}
{% endfor %}
I have tried this for a while now and i dont know whether its from template or view.
You can override get_context_data method like this :
class UserDetail(LoginRequiredMixin, DetailView):
model = Profile
template_name = 'outcome/userprofile_detail.html'
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
# Add in a QuerySet of the user posts
all_posts = Post.objects.all()
user_posts = all_posts.filter(profile_id=self.request.user.profile.id)
context['user_posts'] = user_posts
return context
user_detail.html
{% for post in user_posts %}
{{post.text}}
{{post.overview}}
{% endfor %}

'CategoryDetailView' object has no attribute 'get_object'

I am setting up my CategoryDetailView for my CRM. Then this error occurred:
'CategoryDetailView' object has no attribute 'get_object'
here's my code sectrion from views.py:
class CategoryDetailView(LoginRequiredMixin, generic.ListView):
template_name = "clients/category/category_detail.html"
context_object_name = "category"
def get_context_data(self, **kwargs):
context = super(CategoryDetailView, self).get_context_data(**kwargs)
clients = self.get_object().client_set.all()
context.update({
"clients": clients
})
return context
Here's my models.py
class Client(models.Model):
first_name = models.CharField(max_length=30)
middle_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
mobile_number = models.CharField(max_length=12)
organization = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
agent = models.ForeignKey("Agent", null=True, blank=True, on_delete=models.SET_NULL)
category = models.ForeignKey("Category", related_name="clients", null=True, blank=True, on_delete=models.SET_NULL)
class Category(models.Model):
name = models.CharField(max_length=30) # New, Tapped, Active, Closed
organization = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
def __str__(self):
return self.name
Thanks in advance!
You are working with a ListView [Django-doc], not a DetailView [Django-doc], and a ListView indeed has no .get_object(…) method [Django-doc]. You furthermore should specify a model = … or queryset = … to specify with what queryset the DetailView is dealing.
You thus should inherit from the DetailView. You can also work with self.object to prevent making an extra query:
from django.views.generic import DetailView
class CategoryDetailView(LoginRequiredMixin, DetailView):
template_name = 'clients/category/category_detail.html'
context_object_name = 'category'
model = Category
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
clients = self.object.client_set.all()
context['clients'] = clients
return context
There is als no reason to add this to the context, in the template, you can simply work with:
{% for client in category.client_set.all %}
{{ client }}
{% endfor %}

django - how to get all the projects for a team?

I am new to Django and have a question I couldn't solve it by myself. It is a big question for me.
I want to show the list of Projects related to a specific Team and show it in a ListView.
I would assume it should check the current user belong to which team and then based on the team, it should list the projects.
I have a two apps in my project: 1) users and 2)projects
users.models:
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.contrib.auth import get_user_model
from django.urls import reverse
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):
return reverse('team_detail', args=[str(self.pk)])
and the project model is
class Project (models.Model):
team= models.ForeignKey(Team,on_delete=models.CASCADE )
title = models.CharField(max_length=150, null=False, blank=False)
notes = models.TextField( null=True, blank=True)
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):
return reverse('project_detail', args=[str(self.pk)])
in projects.views: I made the following codes but cant work out the queryset between two models.
class ProjectPageView(ListView):
model = Project
def get_queryset(self):
queryset = super(ProjectPageView, self).get_queryset()
queryset = queryset.filter( XXXXXXXXXXXXXXX )
return queryset
context_object_name = 'projects_list'
template_name = 'projects/projects.html'
and in the HTML
{% extends '_base.html' %}
{% block title %}Projects{% endblock title %}
{% block content %}
<h1> Project list for this Team : </h1>
{% for project in project_list %}
<div>
<h5>{{ project.title }}</h5>
</div>
{% endfor %}
{% endblock content %}
Really really appreciate your help.
you can get the current user from the request object, then proceed
class ProjectPageView(ListView):
model = Project
def get_queryset(self):
queryset = super(ProjectPageView, self).get_queryset()
user_team = Team.objects.filter(user=self.request.user).first()
queryset = queryset.filter(team=user_team)
return queryset
context_object_name = 'projects_list'
template_name = 'projects/projects.html'

Easiest way to add {{ variable }} from different related model in one template

I got a question. I'm wondering what's the easiest way to add different {{ variable }} from different related model in one template.
I'd like to add some information related to seller rating:
def total_seller_ratings(self):
return self.seller.rating_seller.count()
def avg_seller_ratings(self):
return self.seller.annotate(avg_ratesugar=Avg('rating_seller__ratesugar')).order_by('-avg_ratesugar')
Create a template tag from Middleware? Or is any fastes solution to add another model on my view?
I got a main view for my main page:
#Channel MAIN PAGE
#method_decorator(login_required(login_url='/cooker/login'),name="dispatch")
class ChannelMainPage(generic.DetailView, FormMixin):
model = Channel
context_object_name = 'channel'
template_name = 'channel_detail.html'
form_class = ChannelChatForm
def get_context_data(self, **kwargs):
context = super(ChannelMainPage, self).get_context_data(**kwargs)
context['form'] = self.get_form()
return context
def form_valid(self, form):
if form.is_valid():
form.instance.channel = self.object
form.instance.user = self.request.user
form.save()
return super(ChannelMainPage, self).form_valid(form)
else:
return super(ChannelMainPage, self).form_invalid(form)
def post(self,request,*args,**kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_valid(form)
def get_success_url(self):
return reverse('channel:channel_detail',kwargs={"slug":self.object.slug})
models.py
class Channel(models.Model):
consumer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="channel_consumer", blank=True, null=True)
name = models.CharField(max_length=10)
seller = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="channel_seller")
image = models.ImageField(null=True,blank=True,default='user/user-128.png', upload_to='channel/')
date_created = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField('Make it happen', default=False)
class Rating(models.Model):
channel = models.OneToOneField(Channel,on_delete=models.CASCADE,related_name="rating_channel")
consumer = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.CASCADE,related_name='rating_consumer')
seller = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.CASCADE,related_name='rating_seller')
is_rated = models.BooleanField('Already rated', default=True)
comment = models.TextField(max_length=200)
publishing_date = models.DateTimeField(auto_now_add=True)
ratesugar = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
def __str__(self):
return self.channel.name
One place to add it is on the Model class. This is already available as a variable within the context (see generic.Detailview.get_context_data). It is named "object" and can then be accessed through the templating mechanics.
class Channel(models.Model):
consumer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="channel_consumer", blank=True, null=True)
name = models.CharField(max_length=10)
seller = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="channel_seller")
image = models.ImageField(null=True,blank=True,default='user/user-128.png', upload_to='channel/')
date_created = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField('Make it happen', default=False)
def some_method():
pass
template.html
<div>{{ object.some_method() }}</div>
Finally, on the discussion (code design) of which model to place the desired methods on...
If you want to calculate the average over ALL ratings it belongs on the User model.
If you want an average over the ratings over a given channel then it belongs on the Channel model.
Good luck.
PS. Don't forget to prefetch_related to have avoid slow queries!

django (1.11) manytomanyfield templatetags filter

The task is this: There are doctors, there are specializations. A doctor can have several specializations. It is necessary to draw a conclusion of the list of Doctors by specialization.
Model:
class Doctor(models.Model):
title = models.CharField(max_length=200, verbose_name='Имя')
slug = models.SlugField(unique=True)
image = models.ImageField(null=True, blank=True, verbose_name='Фото')
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True, verbose_name='Создано')
special = models.ManyToManyField('Specialization')
experience= models.CharField(max_length=200, verbose_name='Стаж', blank=True)
category = models.CharField(max_length=200, verbose_name='Категория', blank=True)
content = RedactorField(verbose_name='Контент')
keywords = models.CharField(max_length=1024, blank=True, null=True)
description = models.CharField(max_length=1024, blank=True, null=True)
class Meta:
verbose_name = 'Врача'
verbose_name_plural = 'Врачи'
def __str__(self): # For Python 2, use __unicode__ too
return self.slug
def get_absolute_url(self):
return reverse('show_doctor', kwargs={'slug': self.slug})
class Specialization(models.Model):
name = models.CharField(max_length=200, verbose_name='Название')
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True, verbose_name='Создано')
class Meta:
verbose_name = 'Специализацию'
verbose_name_plural = 'Специализации'
def __str__(self): # For Python 2, use __unicode__ too
return self.name
Templatetags:
from django import template
from doctor.models import Doctor, Specialization
register = template.Library()
#register.inclusion_tag('doctors_list.html')
def get_doctors_list(request):
special_list = Specialization.objects.all()
return {
'doctors_list': Doctor.objects.filter(special=special_list),
'spec_list': special_list
}
HTML Template:
{% for s in spec_list %}
<h3>{{ s.name }}</h3>
<ul>
{% for d in doctors_list %}
<li>{{ d.title }}</li>
{% endfor %}
</ul>
{% endfor %}
Should be: PrtSc . I can not figure it out, help me)
You are going about Django in a totally wrong way when you use a template tag for this purpose. Data is passed to the template through context variables. In your case you nedd a ListView over a Specialization queryset. You should access the doctors through the reverse relation in the Specialization model (doctor_set). Do add a prefetch_related for that value to the queryset too.