Reverse Query Through Django Template File - django

models.py file
class Company(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Contact(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
def __str__(self):
return self.first_name
views.py file
class company_detail(DetailView):
def get(self, request, *args, **kwargs):
company = get_object_or_404(Company, pk=kwargs['pk'])
context = {'company': company}
return render(request, 'crm/company_detail.html', context)
company_detail.html file
{% extends 'base.html' %}
{% block content %}
<div id="container">
<ul>
<li>{{company.name}}</li>
</ul>
{% for company in object_list %}
{{ company.name }}
{% for Contact in company.contact_set.all %}
{{Contact.first_name}}
{% empty %}
<!-- no entries -->
{% endfor %}
{% endfor %}
</div>
{% endblock content %}
I'm trying to get the Contacts who are under that company to show up on the company_detail.html page. How do I reverse query it properly to show all Contacts under that company?
Thanks in advance

There is no object_list in your DetailView's context, only the object. You need to remove the for loop over object_list in the template
{% for contact in company.contact_set.all %}
{{ contact.first_name }}
{% empty %}
<!-- no entries -->
{% endfor %}

Related

Django - Giving a view access to multiple models

I followed a tutorial on Youtube that makes a website to create posts. Currently, I am working on displaying other people's profiles and their posts on their profile pages. I did it by accessing the author of the first post, but it only works if the user posted something. Is there another way to do it?
The view:
class UserProfileView(ListView):
model = Post
template_name = 'blog/user_profile.html' # defaults to <app>/<model>_<viewtype>.html--> blog/post_list.html
context_object_name = 'posts' #defaults to objectlist
paginate_by = 5
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-date_posted')
user_profile.html:
{% extends 'blog/base.html' %}
{% block title %}{{ view.kwargs.username }}'s Profile{% endblock title %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ posts.first.author.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ view.kwargs.username }}</h2>
<p class="text-secondary">{{ posts.first.author.email }}</p>
<p class="article-content">{{ posts.first.author.profile.bio }}</p>
</div>
</div>
{% if posts.first.author == user %}
<a class="btn btn-outline-secondary ml-2" href="{% url 'change_profile' %}">Edit Profile</a>
{% endif %}
</div>
<br>
{% if posts.first.author == user %}
<h3 class="ml-2 article-title">Blogs You Posted</h3>
{% else %}
<h3 class="ml-2 article-title">Blogs By {{ view.kwargs.username }}</h3>
{% endif %}
And the Post and Profile module:
class Post(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self) -> str:
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk':self.pk})
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
bio = models.CharField(max_length=225, blank=True, default='')
def __str__(self) -> str:
return f"{self.user.username}'s Profile"
def save(self, *args, **kwargs):
super(Profile, self).save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
img.thumbnail((300,300))
img.save(self.image.path)
First off, you probably don't need .first in your template, because you are using the first item from the QuerySet. If you are accessing a User profile, you can use the DetailView. In addition, you can try from a different page and provide filtered posts in context. Something like this, for example.
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['posts'] = Post.objects.filter(author=user) # from kwargs
return context
#template
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
<li>{{ post.content }}</li>
<li>{{ post.date_posted }}</li>
{% endfor %}
</ul>
PS Regards to Corey.

How i can compare models in template

Why this compare code not work? I want to display all departments where departments filial = filial, but i got failure only. Thanks very much for you answers!
{% for filial in filials %}
{{ filial }}
{% for dep in departments %}
{{ dep }}
{% if dep.Filial == filial.pk %}
IFIFIFIFIF{{ dep.fullname }}
{% endif %}
{% endfor %}
<br>
{% endfor %}
models:
class Filials(models.Model):
Fullname=models.CharField(max_length=30,blank=False)
Entity=models.CharField(max_length=20,blank=True)
City=models.CharField(max_length=15,blank=True)
INN = models.IntegerField(max_length=20,blank=True,null=True)
def __str__(self):
return self.Fullname
def get_absolute_url(self):
return f'/{self.id}'
class Department(models.Model):
Filial=models.ForeignKey(Filials, on_delete=models.CASCADE,related_name='department', blank=True)
Fullname = models.CharField(max_length=30,blank=False)
def __str__(self):
return self.Fullname

how to implement search that can access complete database in Django

My views.py
class SearchView(TemplateView):
template_name = 'search.html'
def get(self, request, *args, **kwargs):
q = request.GET.get('q', '')
self.results = Item.objects.filter(title__icontains=q)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
return super().get_context_data(results=self.results, **kwargs)
My urls.py
url(r'^search/$', SearchView.as_view(), name='search')
My search.html
{% extends 'base.html' %} {% load static %} {% block content %}
<body>
<h1>Search Result</h1>
<ul>
{% for item in q %}
<li>
{{ q.title }}, {{ q.price }}
</li>
{% endfor %}
</ul>
</body>
{% endblock%}}
My nav.html
<form method="GET" action="{% url 'core:search' %}">
This is the code that i used but due to some missing or error in this above code i can't get any data if i make any search in my website, Can some one please tell me what is the mistake i have done.
Thank you.
My Models.py
class Item(models.Model):
title = models.CharField(max_length=50)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
model_no = models.CharField(max_length=100)
try this:
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs)
context['results'] = self.results
return context
in html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<body>
<h1>Search Result</h1>
<ul>
{% for item in results %}
<li>
{{ item.title }}, {{ item.price }}
</li>
{% endfor %}
</ul>
</body>
{% endblock%}}

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

CreateView Model Objects to a template

So I am trying to pass a list of objects into my template. I want my profile.html to reflect the information in the model. I found some documentation on ListView but nothing on CreateView.
The only thing that is passing through to the template is {{ user.username }}. Any suggestions would be greatly appreciated.
profile.html
{% extends 'base.html' %}
{% block title %}User Profile{% endblock %}
{% block content %}
{% if user.is_authenticated %}
<p>User: {{ user.username }} logged in.</p>
<p>homepage</p>
<p>logout</p>
{% else %}
login |
signup
{% endif %}
{% endblock %}
models.py
class Volunteer(CustomUser):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, primary_key=True)
about_me = models.TextField(default='')
class Meta:
db_table = "volunteer"
forms.py
class VolunteerSignUpForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = Volunteer
fields = ("username", "email", "first_name", "last_name",)
#transaction.atomic
def save(self):
user = super(VolunteerSignUpForm, self).save(commit=False)
user.is_volunteer = True
user.save()
return user
views.py
class VolunteerSignUp(CreateView):
form_class = VolunteerSignUpForm
success_url = reverse_lazy('login')
template_name = 'volunteer_signup.html'
#added code from answer
def get_context_data(self, **kwargs):
context = super(VolunteerSignUp, self).get_context_data(**kwargs)
context['profile_list'] = Volunteer.objects.all()
return context
profile.html Here are some things iv tried to get the info across that didn't work.
<ul>
{% for volunteer in object_list %}
<li>{{ volunteer.about_me }}</li>
{% endfor %}
</ul>
<ul>
{% for volunteer in profile_list %}
<li>{{ volunteer.about_me }}</li>
{% endfor %}
</ul>
{% if profile_list %}
{% else %}
<p>There is no info.</p>
{% endif %}
You can use get_context_data() method in your class.
class VolunteerSignUp(CreateView):
form_class = VolunteerSignUpForm
success_url = reverse_lazy('login')
template_name = 'volunteer_signup.html'
def get_context_data(self, **kwargs):
data = super(VolunteerSignUp, self).get_context_data(**kwargs)
data['profile_list'] = 'your queryset goes here'
return data