Check if all objects belong to a list django - python

Template:
{% for level in levels %}
{% if level.todo_set.all in tasks %}
<li>
<img src="{{ level.badge.url }}" alt="" />
</li>
{% else %}
<li>
<img src="{{ level.locked_badge.url }}" alt="" />
</li>
{% endif %}
{% endfor %}
views.py:
#login_required(login_url="/account/login/")
def StudentPublicProfile(request, pk=None):
student = User.objects.get(pk=pk)
levels = Level.objects.all()
todos = ToDo.objects.all()
list = []
tasks = Task.objects.filter(student=student)
for task in tasks:
list.append(task.todo)
context = {"student": student, "levels": levels, "tasks": list, "todos": todos}
return render(request, "student_public_profile2.html", context)
models.py:
class Level(models.Model):
number = models.IntegerField()
badge = models.ImageField()
locked_badge = models.ImageField()
timestamp = models.DateTimeField(
auto_now_add=True, auto_now=False, blank=True, null=True
)
unlock = models.CharField(max_length=10, default="A")
def __str__(self):
return str(self.number)
def get_absolute_url(self):
return reverse("student:level-detail", kwargs={"pk": self.pk})
class ToDo(models.Model):
level = models.ForeignKey(Level, on_delete=models.CASCADE)
name = models.CharField(max_length=150)
description = models.TextField()
timestamp = models.DateTimeField(
auto_now_add=True, auto_now=False, blank=True, null=True
)
def __str__(self):
return self.name
class Task(models.Model):
level = models.ForeignKey(Level, on_delete=models.CASCADE)
todo = models.ForeignKey(ToDo, on_delete=models.CASCADE)
student = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=150)
content = models.TextField()
timestamp = models.TimeField(auto_now=True)
datestamp = models.DateField(auto_now=True)
like = models.ManyToManyField(User, related_name="user_likes", blank=True)
is_verified = models.BooleanField(default=False, blank=True)
def __str__(self):
return self.title
Basically, each level contains multiple todos. I want to check if all todos of the level are contained in the tasks list. This is what I'm doing in the template. But I'm not getting a correct result. What could be the issue here? Here I'm checking if all todos of a level are completed by a particular user. Only when a todo is completed it gets saved in Task

You are probably best to handle this inside your view.
for level in levels_list:
if Todo.objects.filter(level=level).count() == Task.objects.filter(student=student, level=level).count():
return (level completion code)

levellist = []
for level in levels:
if (
ToDo.objects.filter(level=level).count()
== Task.objects.filter(student=student, level=level).count()
):
levellist.append(level.number)
perc = (len(levellist) / len(levels)) * 100
In Template:
{% for level in levels %}
{% if level.number in levellist %}
<li>
<a href="javascript:;"><img src="{{ level.badge.url }}"
alt=""/></a>
</li>
{% else %}
<li>
<a href="javascript:;"><img src="{{ level.locked_badge.url }}"
alt=""/></a>
</li>
{% endif %}
{% endfor %}
Found a fix!

Related

Why Am I getting "None" when using ForeignKey on integer value from another model that I know that have integer number?

I wanted to ask you for your help. I have two models. In the first one I wanted to reference foriegn key from the second one to be able to print votescore that I store there.
My models.py :
class Question(models.Model):
question = models.CharField(max_length=300)
answered = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
datecompleted = models.DateTimeField(null=True, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
votesscore = models.ForeignKey('VoteQuestion', on_delete=models.CASCADE, null=True, blank=True, related_name='question_votesscore')
def __str__(self):
return self.question
class VoteQuestion(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE, blank=False, null=True)
votesubmitted = models.DateTimeField(null=True, blank=True)
votesscore = models.IntegerField(default='0')
amountofvotes = models.IntegerField(default='0')
def __str__(self):
return self.votesscore
class Meta:
unique_together = ['user', 'question', 'votesscore']
Next in my views.py:
def home(request):
allquestionswithanswers = Question.objects.filter(datecompleted__isnull=False)
allquestionswithoutanswers = Question.objects.filter(datecompleted__isnull=True)
return render(request, 'main/home.html', {'allquestionswithanswers': allquestionswithanswers, 'allquestionswithoutanswers': allquestionswithoutanswers})
And in my home.html I am calling it like this:
{% for question in allquestionswithanswers %}
<li>
{{ question }} Score: {{ question.votesscore }} {{ question.user }}
<br><br>
<form class='my-ajax-form' method='POST' action='' data-url="{% url 'questionvoteup' question.id %}" >
{% csrf_token %}
<button type='submit'>UP</button>
</form>
{% for answer in question.answer_set.all %}
{{ answer }}<br>
{% endfor %}
</li>
{% endfor %}
And when I try to print {{ question.votesscore }} I get value "None". Yet I am sure that in database it is an integer value. Could you please point me in right direction with this ?
Thanks and Cheers

django iterate over a list that is an item of a queryset

I have a list that is generated by a method on one of my models. On the home page it works wonderfully, however when I go to a detail view of one project I can access all the parts of that project as they are direct fields of the Model, but I can't access the items in the list.
Model:
class Project(models.Model):
date_published = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
area = models.ForeignKey(Area, on_delete=models.PROTECT)
title = models.CharField(max_length=128, unique=True)
slug = models.SlugField(max_length=64)
summary = models.CharField(max_length=256)
others = models.CharField(max_length=128, blank=True)
deadline = models.DateField(null=True, blank=True)
priority = models.ForeignKey(Priority, on_delete=models.PROTECT)
closed = models.DateTimeField(null=True, blank=True)
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.title)
super(Project, self).save(*args, **kwargs)
#property
def updates(self):
updates = []
sequence_id = 1
categories = set(self.update_set.all().values_list(
'category__id', flat=True))
for cat_id in categories:
a = Update.objects.filter(
project=self, category__id=cat_id).order_by('added').last()
if cat_id == sequence_id:
updates.append(a)
else:
for i in range(cat_id - sequence_id):
updates.append('null')
updates.append(a)
sequence_id = cat_id
sequence_id += 1
return updates
class Update(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
category = models.ForeignKey(UpdateCategory, on_delete=models.PROTECT)
update = models.TextField(max_length=240, blank=True)
added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.update
The view is simple:
class ProjectDetailView(DetailView):
template_name = 'project_portal/project_detail.html'
queryset = Project.objects.all()
and here is the dynamic url that I am using:
path('project/<int:pk>/',
ProjectDetailView.as_view(), name='project_detail'),
As for the template, I'm lost, here is one of the things I have tried:
<!DOCTYPE html>
{% extends "project_portal/base.html" %}
{% block home %}
<div id="main">
<div id="content">
<div>
<h1>{{ object.title }}</h1>
<h1>hello</h1>
{% if object_list %}
{% for item in updates %}
<p>{{ item }}</p>
{% endfor %}
{% else %}
<h2>No records found for this project</h2>
{% endif %}
</div>
</div>
</div>
{% endblock %}
What do I need to do to access the "updates" list that gets generated?
update is a property of the model instance, you need to access it from there like any other attribute. Also note, there is no object_list in a detail view.
<div>
<h1>{{ object.title }}</h1>
<h1>hello</h1>
{% for item in object.updates %}
<p>{{ item }}</p>
{% endfor %}
</div>

Filter queries inside templates django

models:
class Level(models.Model):
number = models.IntegerField()
badge = models.ImageField()
locked_badge = models.ImageField()
timestamp =
models.DateTimeField(auto_now_add=True,auto_now=False,blank=True,
null=True)
unlock = models.CharField(max_length=10,default="A")
def __str__(self):
return str(self.number)
def get_absolute_url(self):
return reverse('student:level-detail', kwargs={'pk': self.pk})
class ToDo(models.Model):
level = models.ForeignKey(Level, on_delete=models.CASCADE)
name = models.CharField(max_length=150)
description = models.TextField()
timestamp =
models.DateTimeField(auto_now_add=True,auto_now=False,blank=True,
null=True)
def __str__(self):
return self.name
class Task(models.Model):
level = models.ForeignKey(Level, on_delete=models.CASCADE)
todo = models.ForeignKey(ToDo, on_delete=models.CASCADE)
student = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=150)
content = models.TextField()
timestamp = models.TimeField(auto_now=True)
datestamp = models.DateField( auto_now=True)
like =
models.ManyToManyField(User,related_name='user_likes',blank=True)
is_verified=models.BooleanField(default=False,blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('student:dashboard')
objects = PostManager()
#property
def comments(self):
instance = self
qs = Comment.objects.filter_by_instance(instance)
return qs
#property
def get_content_type(self):
instance = self
content_type =
ContentType.objects.get_for_model(instance.__class__)
return content_type
Template:
{% for level in levels %}
{% if tasks.filter(student=student,level=level).count ==
todos.filter(level=level).count %}
<li>
<img src="{{ level.badge.url }}" alt="" />
</li>
{% else %}
<li>
<a href="javascript:;"><img src="{{
level.locked_badge.url }}" alt="" /></a>
</li>
{% endif %}
{% endfor %}
sample view:
#login_required(login_url='/account/login/')
def StudentPublicProfile(request,pk=None):
student = User.objects.get(pk=pk)
levels = Level.objects.all()
todos=ToDo.objects.all()
tasks=Task.objects.all()
context={
'student': student,
'levels' : levels,
'tasks' : tasks,
'todos' : todos,
}
return render(request, 'student_public_profile2.html', context)
This might need a little explanation. I have 3 models- Level Todo and Task. Each level contains many todos.When a todo is completed,ie,when a todo form is submitted,It gets saved in the Task model.The form uses model form,so basically task is the set of completed todos of the user of a level. I want to display badges for the levels based on a condition which is : If all the todos of a level is completed,it should display one type of badge,if not it should display a locked badge!How do i go about this?
I came accross template tags..I make my custom tags like this:
#register.filter
def completed(tasks,student, level):
return tasks.filter(student=student,level=level).count()
#register.filter
def alltodos(todo, level):
return todo.filter(level=level).count()
How to call function from template for this to work correctly?
{% for level in levels %}
{% if tasks|completed:tasks,student,level ==
todos|alltodos:todos,level %}
<li>
<a href="javascript:;"><img src="{{
level.badge.url }}" alt="" /></a>
</li>
{% else %}
<li>
<a href="javascript:;"><img src="{{
level.locked_badge.url }}" alt="" /></a>
</li>
{% endif %}
{% endfor %}

Retrieve a filtered ForeignKey with Django

I have three main models, Picture, Place and PlaceRating:
class Picture(models.Model):
file = ImageField(max_length=500, upload_to="images")
user = models.ForeignKey(User, null=True, related_name="userpictures")
place = models.ForeignKey(Place, null=True, related_name='pictures')
class PlaceRating(models.Model):
place = models.ForeignKey(Place, null=True, related_name="placeratings")
user = models.ForeignKey(User, null=True, related_name="userratings")
rating = models.DecimalField(null=True, max_digits=4, decimal_places=1)
class Place(models.Model):
name = CharField(max_length=50)
I would like to display the place's rating given by the user, together with the place's image, but I cannot manage to do that as I would need to filter the ForeignKey and Django does not seem to allow that.
Example of what I would like to do:
View:
pictures = Picture.objects.filter(user=request.user)
Template:
{% for picture in pictures %}
<img src="{{ picture.file.url }}" class="bigpicture">
{{ picture.place.placeratings.0.rating|user:picture.user }}
{% endfor %}
For information, I managed to do it with templatetags, but this generates a lot of different queries to the database which I can't prefetch..:
{% for picture in pictures %}
<img src="{{ picture.file.url }}">
{% getplaceratingrelatedtopic picture.place.id picture.user.id %}
{% endfor %}
And:
#register.simple_tag
def getplaceratingrelatedtopic(placeid, userid):
print(placeid)
theplace = Place.objects.get(id=placeid)
user = User.objects.get(id=userid)
placerating = PlaceRating.objects.filter(author=user, place=place).last()
if rating:
return placerating.rating
else:
return ""
I work with Python 2.7/Django 1.9.
Any clue ? Thanks a lot!
You should move the logic to the model and use it in the template.
class Picture(models.Model):
file = ImageField(max_length=500, upload_to="images")
user = models.ForeignKey(User, null=True, related_name="userpictures")
place = models.ForeignKey(Place, null=True, related_name='pictures')
class PlaceRating(models.Model):
place = models.ForeignKey(Place, null=True, related_name="placeratings")
user = models.ForeignKey(User, null=True, related_name="userratings")
rating = models.DecimalField(null=True, max_digits=4, decimal_places=1)
class Place(models.Model):
name = CharField(max_length=50)
#property
def rating(self):
return self.placeratings.get().rating
{% for picture in picture_list %}
<img src="{{ picture.file.url }}" class="bigpicture">
{{ picture.place.rating }}: {{ picture.user.username }}
{% endfor %}

Creating a for loop with results based on another table

I have two lists of objects, buildnumbers and partrequestnumbers.
Both list contain buildnumbers, and what I am trying to achieve is a html list of the buildnumbers with their associated parturequestnumbers, the link being the buildnumber. So far I have had a look at numpy arrays and a few for loop suggestions without achieving what I am trying to achieve. My current for loop just loops through all of the numbers...
The image shows the build list, I'd like the partnumbers next to it too
Django Views:
def manufacturelist(request, mug=None, slug=None):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
partrequests = PartRequestNumbers.objects.order_by('-id')
latest_preparebuild_list = PrepareBuild.objects.order_by('-pub_date')
builds=[]
for preparebuild in latest_preparebuild_list:
bb = preparebuild.buildno
builds.append(PartRequestNumbers.objects.filter(buildno=bb))
context = {
"latest_preparebuild_list": latest_preparebuild_list,
"partrequests": partrequests,
"builds": builds,
}
return render(request, "buildpage/manufacturelist.html", context)
HTML:
{% if latest_preparebuild_list %}
<ul>
{% for preparebuild in latest_preparebuild_list %}
<li><a class = "subtitle" >{{ preparebuild.buildno }}: </a><a style= "float: right" href="/buildpage/{{ preparebuild.part_request }}/manufacturebuild">{{ partrequests.part_request }}</a><p style= "float: right">{{ preparebuild.build_status }}</p></li>
{% for partrequest in partrequests %}
<center>{{ partrequest.part_request }} </center>
{% endfor %}
{% endfor %}
</ul>
{% else %}
<p>No builds are available.</p>
{% endif %}
models:
class PrepareBuild(models.Model):
pub_date = models.DateTimeField(default= datetime.now)
STATUS = Choices('Complete', 'In-Build', 'Awaiting Build', 'Cancelled', 'Design Issue', 'M/C Issue')
buildstatus = StatusField()
status_changed = MonitorField(monitor='buildstatus')
buildno = models.CharField(_('Build Number'),max_length=10, default= bnumber)
current_location = models.ForeignKey(BuildLocation, default='', null=True)
machine = models.ForeignKey(Machine, max_length=10, default ="")
batchno = models.CharField(_('Batch Number'),max_length=100, default="")
partnumber = models.CharField(_('Part Number(s)'), max_length = 100, default = 'e.g. 002109_1')
buildtime = models.CharField(_('Build Time'), default= '', max_length=100)
buildnotes = models.CharField(_('Build Notes'), max_length=200, default = "", blank=True)
mug = models.SlugField(unique=True, null=True)
def __unicode__(self):
return self.buildno or default
class PartRequestNumbers(models.Model):
buildno = models.CharField(_('Build Number'),max_length=10, default= bnumber)
part_request = models.ForeignKey(PartRequest, related_name='PR Number+', null=True)
def __str__(self):
return '{}' .format(self.part_request)

Categories