I have created a template that displays items from a loop, Within the loop there is a condition, but the condition does not work unless specified explicitly.
{% extends 'blog/base.html' %}
{% block content %}
<h3>{{ user.username }}</h3>
{% for project in projects %}
{% if user.username == 'testuser' %}
<h5>{{ project.title }}</h5>
<p>{{ project.description }}</p>
<p>{{ project.objectives }}</p>
<pre>{{ project.score }}</pre>
<pre>{{ project.student_id }}</pre>
{% endif %}
{% endfor %}
{% endblock content %}
The above code works perfectly and returns the records assigned to the user named testuser.
But if I write the code as below, it skips all records
{% extends 'blog/base.html' %}
{% block content %}
<h3>{{ user.username }}</h3>
{% for project in projects %}
{% if user.username == project.student_id %}
<h5>{{ project.title }}</h5>
<p>{{ project.description }}</p>
<p>{{ project.objectives }}</p>
<pre>{{ project.score }}</pre>
<pre>{{ project.student_id }}</pre>
{% endif %}
{% endfor %}
{% endblock content %}
I have added the code from the model
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Projects(models.Model):
title = models.CharField(max_length=150)
description = models.TextField()
objectives = models.TextField()
score = models.IntegerField()
#file = models.FileField()
date_posted = models.DateTimeField(default=timezone.now)
student_id = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.title
The student_id is a User object, not a string, so here you are comparing a string (the username) with a User object, and a User with username 'testuser', is not the same as a string 'testuser'.
The most elegant solution is probably to compare the user with the user, so:
{% if user == project.student_id %}
So we omit the .username, and compare a User object with a User object.
Note: enumeration (especially in a template, but also in the Django layer itself), is not efficient, you should make a query that
does the filtering for you.
You can filter a queryset with:
user_projects = Project.objects.filter(student_id=request.user)
in your view to obtain only projects for which the logged in user is
the student.
Note: A ForeignKey usually does not have an _id suffix. Django will automatically add an extra field named fieldname_id that
stores the primary key to which the foreign key refers. After all, a
ForeignKey in Django will lazy load the related object.
Related
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 %}
i am making a twitter like clone(just to learn how things works in django)
so i am basically trying to set up a many_to_many relationship.
i want to add the functionality of showing 'FOLLOWED_BY' and 'FOLLOWING' to a user profile but list of 'FOLLOWED_BY' is not showing on the page please someone help me!
in the models.py i have define two relationship
user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL, related_name='profile', null=True,
blank=True)
following = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name='followed_by', blank=True)
and in the user_detail.html i have the code for how a profile should look like
this is the models.py module:
from django.conf import settings
from django.db import models
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL, related_name='profile',
null=True,
blank=True)
following = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name='followed_by', blank=True)
def __str__(self):
return str(self.following.all().count())
below is the code for user_detail.html file:
{% extends "base.html" %}
{% block content %}
<div class="row">
<div class="col-sm-3 col-xs-12" style="background-color: yellow">
<h1>{{ object.username }}</h1>
<p>Followers: {{ object.followed_by.count }}</p>
</div>
<div class="col-sm-9 col-xs-12">
<h1>Tweets</h1>
{% for tweet in object.tweet_set.all %}
{{ tweet }}<br/>
{% endfor %}
<hr/>
<h1>Following</h1>
{% for user in object.profile.following.all %}
<a href='/{{ user.username }}'>{{ user.username }}</a><br/>
{% empty %}
<h4>Not following any users</h4>
{% endfor %}
<hr/>
<h1>Followed By</h1>
{% for profile in object.profile.followed_by.all %}
<a href='/{{ profile.user.username }}'>{{ profile.user.username }}</a><br/>
{% empty %}
<h4>Not followed by any user</h4>
{% endfor %}
</div>
{% endblock content %}
for user profile i am getting the FOLLOWING field as i want but FOLLOWED_BY field is not showing how can i do that (what changes should i do in my code)??
You defined a following field that points to the user model, not to a Profile. As a result a Profile has no followed_by relation, a User object has.
I think it probably is better to let following point to Profile, like:
class UserProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
related_name='profile',
null=True,
blank=True
)
following = models.ManyToManyField(
'self',
related_name='followed_by',
symmetrical=False,
blank=True
)
def __str__(self):
return str(self.following.all().count())
Then you can render this like:
<div class="col-sm-3 col-xs-12" style="background-color: yellow">
<h1>{{ object.username }}</h1>
<p>Followers: {{ object.followed_by.count }}</p>
</div>
<div class="col-sm-9 col-xs-12">
<h1>Tweets</h1>
{% for tweet in object.tweet_set.all %}
{{ tweet }}<br/>
{% endfor %}
<hr/>
<h1>Following</h1>
{% for profile in object.profile.following.all %}
<a href='/{{ profile.user.username }}'>{{ profile.user.username }}</a><br/>
{% empty %}
<h4>Not following any users</h4>
{% endfor %}
<hr/>
<h1>Followed By</h1>
{% for profile in object.profile.followed_by.all %}
<a href='/{{ profile.user.username }}'>{{ profile.user.username }}</a><br/>
{% empty %}
<h4>Not followed by any user</h4>
{% endfor %}
</div>
Your code has however some (serious) anti-patterns. The most important one is that you should not write business logic in the template. You should use the view for that. For example you can specify in the view a context like:
context = {
'tweets': object.tweet_set.all()
'followers': object.profile.following.select_related('user').all()
'followed_by': object.profile.followed_by.select_related('user').all()
}
We here can also use a .select_related() [Django-doc] that will boost performance significantly, since now all the users are fetched in the same query.
You also better use the {% url ... %} template tag [Django-doc] to construct queries. So instead of writing:
<a href="/{{ profile.user.username }}">
it is better to construct the query using a reverse lookup like:
<a href="/{% url 'profile_view' username=profile.user.username %}">
I trying to access the ImageField of a Model which is assigned via ForeignKey to another Model.
I have different Animal Apps in my Projects, with almost the same structure, like the following models.py. On the landingpage of My Project I want to display the last 3 entry of every (Species) Models with Name and Picture. If the Species has no Picture I would like to display the ImageField of the Farm, which is connected via ForeignKey to my species.
cows/models.py
class Farm(models.Model):
name = models.CharField(max_length=100)
farm_img = models.ImageField(upload_to='farm_images/',
max_length=255, null=True, blank=True)
class Cows(models.Model):
farm = models.ForeignKey(Farm, on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=100)
entry_date = models.DateField(null=True, blank=True)
cow_img = models.ImageField(upload_to='farm_images/',
max_length=255, null=True, blank=True)
Views.py
class HomeIndex(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context['chickens'] = Chicken.objects.order_by('-entry_date')[:3]
context['cows'] = Cows.objects.order_by('-entry_date')[:3]
context['cats'] = Cats.objects.order_by('-entry_date')[:3]
return context
home.html
<….>
{% for somecow in cows %}
<div class="col-3" id="p1">
<h2>{{ somecow.name }}</h2>
<h2>{{ somecow.entry_date }}</h2>
{% if somecow.cow_img %}
<img src="{{ somecow.cow_img.url }}" alt="Mod" height="100">
{% endif %}
</div>
{% endfor %}
<….>
Until here it worked.
But how can i access the FK.Model of the Model?
Or in other Words how can I tell Django:
“If you found no cow Picture in Cow.Model,then show a Farm picture from the assigned Farm.Model?”
As I understand I can access the assigned FK Models via
{% for something in MyModel1.MyModel2_set.all %}.
my approach for home.html
<….>
{% for somecow in cows %}
<div class="col-3" id="p1">
<h2>{{ somecow.name }}</h2>
<h2>{{ somecow.entry_date }}</h2>
{% if somecow.cow_img %}
<img src="{{ somecow.cow_img.url }}" alt="Mod" height="100">
{% else %}
{% for farm in somecow.farm_set.all %}
{% if farm.farm_img %}
<img src="{{ farm.farm_img.url }}" alt="Mod" height="100">
{% endif %}
{% endfor %}
{% endif %}
</div>
{% endfor %}
<….>
So far I received no error Message, but I also see no Farm Image. I am sure I mixed something up in home.html. On the other Side I think I maybe I missed something in my view, something like MyModel.objects.all()
I am thankful for every hint.
You're overcomplicating things. There is only a single farm per cow: you just need to access it directly.
{% else %}
{% if cow.farm.farm_img %}
<img src="{{ cow.farm.farm_img.url }}" alt="Mod" height="100">
{% endif %}
{% endif %}
On this case my problem arise displaying extended values of my user model in my index.html
here my models.py
from django.db import models
from django.contrib.auth.models import User
def url(self,filename):
ruta = "MultimediaData/Users/%s/%s"%(self.user.username,filename)
return ruta
class userProfile(models.Model):
user = models.OneToOneField(User)
photo = models.ImageField(upload_to=url)
telefono = models.CharField(max_length=30)
email = models.EmailField(max_length=75)
def __unicode__(self):
return self.user.username
my index.html:
{% extends 'base.html' %}
{% block title %} Inicio - Bienvenidos {% endblock %}
{% block content %}
<p>Dracoin, el portal que facilitará tu vida</p>
{% if user.is_authenticated %}
<p>Bienvenido {{ user.username }}</p>
{% if user.get_profile.photo %}
<img src="/media/{{user.get_profile.photo}}" width="100px" height="100px"/>
{% endif %}
{% if user.get_profile.telefono %}
<p>Numero Tel: {{user.get_profile.telefono}}</p>
{% endif %}
{% endif %}
{% endblock %}
I don't have problem managing that information in my admin panel but i cant view that information in my index. I believe the mistake is in {% if user.get_profile.xxxx %} calling but I cant solve it.
apologizeme in advance if I overlook something.
Thanks!!
get_profile() was deprecated in django 1.5, and removed in django 1.7.
Try {{ user.userprofile.xxxx }} instead.
I'm trying to build a page with all of the model's categories and associated entries in one view. I followed tips from here django class based views for all categories with all entires and here Get all categories and items in category but I still can't get it to work. Any ideas ?
-- models
class Category(models.Model):
name = models.CharField(max_length=50)
def __unicode__(self):
return self.name
class Feed(models.Model):
name = models.CharField(max_length=100)
url = models.CharField(max_length=100)
category = models.ForeignKey(Category)
user = models.ManyToManyField(User)
def __unicode__(self):
return self.url
-- views
def category_page(request):
object_list = Category.objects.all()
context = {'object_list': object_list,}
return render(request, 'category_page.html', context)
-- template category_page.html
{% block content %}
{% for category in object_list %}
{{ category.name }}
{% for entry in category.entry_set.all %}
{{ category.name}}
{% endfor %}
{% endfor %}
{% endblock content %}
I'm getting list of all categories displayed but no entries.
thanks
-M
Here
{% for entry in category.entry_set.all %}
{{ category.name}}
{% endfor %}
should be
{% for entry in category.feed_set.all %}
{{ entry.name}}
{% endfor %}
{{ category.name}} inside the forloop for entries is what is not displaying the correct name.
Also, what is entry_set ? If you are not specifying a related_name, you need to use the lower-case model name to get the related objects (feed_set in this case).
Something like this:
category.feed_set.all
Summing it up,
{% block content %}
{% for category in object_list %}
{{ category.name }}
{% for entry in category.feed_set.all %}
{{ entry.name}}
{% endfor %}
{% endfor %}
{% endblock content %}
You can read more on related objects here
If this is your actual code, the problem is variable names in your template.
{% for category in object_list %}
{{ category.name }}
{% for entry in category.feed_set.all %}
{{ entry.name}}
{% endfor %}
{% endfor %}
Specifically, you refer to entry_set, but that's not the reverse name for the relationship since your model name is Feed rather than Entry and you haven't declared a non-default related_name argument.
Also, you're re-printing your category name instead of the name of the Feed instances.