Django : How to check if element in the queryset? - django

I'd liket to make is current_user exist in queryset, so i try:
{% if obj.payer.name == current_user.username %}
{{ obj.price|intcomma }} / {{obj.dutch_payer.all.count}}</p>
<p>={{ obj.price|div_payer_me:obj.dutch_payer.all.count|intcomma }}</p>
{% else %}
{% if current_user.username in obj.dutch_payer.filter(name=current_user.username) %}
{{ obj.price|intcomma }} / {{obj.dutch_payer.all.count|add1}}</p>
<p>={{ obj.price|div_payer_notme:obj.dutch_payer.all.count|intcomma }}</p>
{% else %}
0
{% endif %}
{% endif %}
but error occur :
Could not parse the remainder: '(name=current_user.username)' from 'obj.dutch_payer.filter(name=current_user.username)'
Tempfriend model:
class Tempfriend(core_models.TimeStampedModel):
name = models.CharField(max_length=30)
belongs_to = models.ForeignKey(
user_models.User, on_delete=models.CASCADE, related_name="belongs_to")
def __str__(self):
return self.name
moneylog model:
class Moneylog(core_models.TimeStampedModel):
moneybook = models.ForeignKey(
moneybook_models.Moneybook, on_delete=models.CASCADE)
pay_day = models.DateTimeField(default=NOW)
payer = models.ForeignKey(
tempfriend_models.Tempfriend, on_delete=models.CASCADE, related_name="payer")
dutch_payer = models.ManyToManyField(
tempfriend_models.Tempfriend, related_name="dutch_payer", blank=True)
price = models.IntegerField()
category = models.CharField(max_length=10)
memo = models.TextField()
objects = models.Manager()
as you see, dutch_payer and current_user is different model.
How can I check the is there current_user in dutch_payer?
Tried:
#register.filter
def user_in_dutch_payers(current_user, obj):
return obj.dutch_payer.filter(name=current_user.username).exists()

You can't use queries directly in template (templates are writen in Django template language). Instead you can use simple tag:
Add your custom tag(s) in settings.py:
TEMPLATES = [
{
'OPTIONS': {
'builtins': [
'myprojectname.templatetags.custom_tags',
Next, put this file inside your app templatetags/custom_tags.py
from django import template
register = template.Library()
#register.simple_tag
def user_in_dutch_payers(current_user, obj):
return obj.dutch_payer.filter(name=current_user.username).exists()
And finally use tag in template:
{% user_in_dutch_payers current_user obj as check_user_in_dutch_payers %}
{% if check_user_in_dutch_payers %}
{{ obj.price|intcomma }} / {{obj.dutch_payer.all.count|add1}}</p>
<p>={{ obj.price|div_payer_notme:obj.dutch_payer.all.count|intcomma }}</p>
{% else %}
0
{% endif %}

Related

Can I access the child model from the parent?

I have created a productForArt and albomForArt model
From producForArt I inherit to albomForArt
Making a view based on generic.ListView
And I output it in the template,
Can I access the number Of Pages field in the template
albomForArt models, or in this case Django returns an object of the albomForArt model, but with properties that were inherited from albomForArt?
models
from django.db import models
class productForArt(models.Model):
class Meta:
verbose_name = u'товар'
verbose_name_plural = u'товары'
price = models.IntegerField(verbose_name="цена", default=0)
title = models.CharField(max_length=300, verbose_name="название товара", null=True)
description = models.CharField( max_length=1000,verbose_name="Описание товара", null=True)
type = models.ForeignKey('typeProductForArt', on_delete=models.PROTECT)
def getType(self):
return self.type
def __str__(self):
return str(self.title) + ' по цене' + str(self.price) + ' шт'
class albomForArt(productForArt):
numberOfPages = models.IntegerField(default=10,verbose_name="количество станиц" )
class typeProductForArt(models.Model):
title = models.CharField(max_length=200, default="none")
def __str__(self):
return self.title
vievs
from django.views import View, generic
from .models import productForArt
class startPage(generic.ListView):
model = productForArt
template_name = "startPage.html"
context_object_name = "productForArt_list"
queryset = productForArt.objects.all()[:20]
templates
{% if productForArt_list %}
<section class="productsStartpage">
{% for productForArt in object_list %}
<article class="productForArtStartpage">
<h1>{{productForArt.title}}</h1>
<p>{{productForArt.description}}</p>
{% endif %}
</article>
{% endfor %}
</section>
{% else %}
<p>товара нету</p>
{% endif %}
You can use One-to-one relationships
class albomForArt(productForArt):
product_for_art = models.OneToOneField(productForArt, on_delete=models.CASCADE)
numberOfPages = models.IntegerField(default=10,verbose_name="количество станиц" )
Then in Template
{% if productForArt_list %}
<section class="productsStartpage">
{% for productForArt in object_list %}
<article class="productForArtStartpage">
<h1>{{productForArt.product_for_art.title}}</h1>
<p>{{productForArt.product_for_art.description}}</p>
{% endif %}
</article>
{% endfor %}
</section> {% else %} <p>товара нету</p>{% endif %}

In Django, is there a way you can limit a user to registering for an event only once?

I'm a newbie to Django, trying to build site to allow people to register for football matches.
At the moment, a user can register multiple times for the same match, which is obviously not ideal! Is there a way that I can identify if the currently logged in user has already registered, and then replace the register button with a message telling them that they have already registered? I guess I need some kind of Boolean value in my EventDetail view, and then I can make a conditional statement in the template, but I'm unsure as to how to implement this. I hope this question is clear, it's my very first post!
views.py:
class EventDetail(View):
def get(self, request, id, *args, **kwargs):
event = get_object_or_404(Event, pk=id)
registrations = Registration.objects.filter(event=event)
total_participants = 0
for person in registrations:
total_participants += 1
if person.guest:
total_participants += 1
remaining_spaces = event.max_participants - total_participants
template = "event_detail.html"
context = {
"event": event,
"total_participants": total_participants,
"registrations": registrations,
"remaining_spaces": remaining_spaces,
}
return render(request, template, context)
template
{% extends "base.html" %}
{% block content %}
<p>{{ event.title }}</p>
<p>{{ total_participants }} / {{ event.max_participants }} ({{ remaining_spaces }} spot{{ remaining_spaces|pluralize }}
remaining!)</p>
{% if total_participants < event.max_participants %}
Register
{% else %}
<p>This event has filled up.</p>
{% endif %}
<h2>Current Participants</h2>
<ul>
{% for person in registrations %}
<li>
{{ person.name }}
{% if person.guest %}
+1
{% endif %}
</li>
{% endfor %}
</ul>
{% endblock %}
models.py
from django.db import models
from django.contrib.auth.models import User
class Event(models.Model):
title = models.CharField(max_length=100)
created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="event_posts")
event_date_and_time = models.DateTimeField()
venue = models.CharField(max_length=100)
max_participants = models.IntegerField()
extra_info = models.TextField(blank=True)
updated_on = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['event_date_and_time']
def __str__(self):
return self.title
class Registration(models.Model):
event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name="event_registration")
name = models.ForeignKey(User, on_delete=models.CASCADE)
ball = models.BooleanField(default=False)
bibs = models.BooleanField(default=False)
guest = models.BooleanField(default=False)
def __str__(self):
return str(self.name)

How do i display the objects related to a foreign key in django

my models:
class Company(models.Model):
name = models.CharField(max_length=250)
def __str__(self):
return str(self.name)
class Products(models.Model):
company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name="display")
engine = models.CharField(max_length=250, blank=True)
cyl = models.CharField(max_length=250, blank=True)
bore = models.CharField(max_length=250, blank=True)
def __str__(self):
return str(self.engine) + " (ref:" + str(self.ref) + ")"
my views.py:
def Companies(request):
context = {
'categories': Company.objects.all()
}
return render(request, 'product_list.html', context)
HTML :
{% for category in categories %}
<h2>{{ category.name }}</h2>
{% for item in category.item_set.all %}
{{ item_engine }}
{% endfor %}
{% endfor %}
how do i display every objects of Products(engine,cyl,bore) following its name
If you want to get related field using ForeignKey try with prefetch_related() method like this
add this in your views.py file
def Companies(request):
context = {
'categories': Products.objects.prefetch_related('company')
}
return render(request, 'product_list.html', context)
this will return object when you try to access your Company object in template like this {{ category.company }} it will give you output like this Company object (1) and you can access all attributes from your Company model.
add this in your template
{% for category in categories %}
<h2>{{ category.company.name }}</h2>
<p>{{ category.engine }}</p>
<p>{{ category.cyl }}</p>
<p>{{ category.bore }}</p>
{% endfor %}
if you delete any Company it will be not displayed on template.

Get Featured Image from different Model

I have 2 model objects, Business & BusinessImage as so, listed with views and index.html. I am trying to list the business's featured image, but it's not happening. I am getting the following error:
'QuerySet' object has no attribute 'businessimage_set'
How can I get the business featured image for a list?
Business
class Business(models.Model):
name = models.CharField("Name", max_length=70, default="Business Name")
slug = models.SlugField()
description = models.TextField("About", max_length=400)
category = models.ManyToManyField(Category, verbose_name="Categories", blank=True)
order = models.IntegerField("Order", default=0)
claimed = models.BooleanField("Claimed", default=False)
featured = models.BooleanField("Featured", default=False)
class Meta:
ordering = ['order']
verbose_name = "Business"
verbose_name_plural = "Businesses"
def __str__(self):
return self.name
BusinessImage
class BusinessImage(models.Model):
business = models.ForeignKey(Business)
image = models.ImageField(upload_to="images/business")
title = models.CharField(max_length=120)
featured = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return self.title
view.py
from .models import Business, BusinessImage
def index_view(request):
latest_business_list = Business.objects.all()
images = latest_business_list.businessimage_set.all()
template = loader.get_template('index.html')
context = RequestContext(request, {
'latest_business_list': latest_business_list,
'images': images,
})
return HttpResponse(template.render(context))
index.html
{% block content %}
<div class="text-center business_title">
<h2>Featured</h2>
</div>
{% if latest_business_list %}
{% for business in latest_business_list|slice:":4" %}
{% if business.active %}
<div class="col-sm-6 col-md-3">
<li>{{ business.name }}</li>
{% for image in latest_business_list.businessimage_set.all %}
{% if image.featured %}
<a href="{% url 'single_product' product.slug %}">
<img src="{{MEDIA_URL}}{{image.image}}" alt="{{image}}">
</a>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endblock %}
businessimage_set is an attribute of a Business instance, but you're trying to access it as an attribute of a queryset (i.e. list of businesses). If your goal is just to be able to access the images for each business in a template, you can leave out images entirely. Instead your template would have:
{% for image in business.businessimage_set.all %}
(Though look into prefetch_related for efficiency.)

Nested loop in Django template

I can't get my head around this. I need to somehow access the object in the parent loop but I'm not sure how. Here is what I've come up with so far. I marked the problematic area in the code with XXX:
Template:
{% for item in ingrcat %}
<h2>{{ item.name }}</h2>
<ul>
{% for ingr in XXX %}
<li>{{ ingr.name }}</li>
{% endfor %}
</ul>
{% endfor %}
XXX - should be a list of ingredients belonging to the ingredience category which is currently being looped through in the parent loop.
View:
def home(request):
if request.user.is_authenticated():
username = request.user.username
email = request.user.email
foods = Food.objects.filter(user=request.user).order_by('name')
ingredients = Ingredience.objects.filter(user=request.user).order_by('name')
ingrcat = IngredienceCategory.objects.filter(user=request.user)
context = {}
for i in ingredients:
context[i.category.name.lower()] = context.get(i.category.name.lower(), []) + [i]
newcontext = {'foods': foods, 'ingredients': ingredients, 'ingrcat': ingrcat, 'username': username, 'email': email,}
else:
context = {}
newcontext = {}
context = dict(context.items() + newcontext.items())
return render_to_response('home.html', context, context_instance=RequestContext(request))
Models:
from django.db import models
from django.contrib.auth.models import User
class IngredienceCategory(models.Model):
name = models.CharField(max_length=30)
user = models.ForeignKey(User, null=True, blank=True)
class Meta:
verbose_name_plural = "Ingredience Categories"
def __unicode__(self):
return self.name
class Ingredience(models.Model):
name = models.CharField(max_length=30)
category = models.ForeignKey(IngredienceCategory, null=True, blank=True)
user = models.ForeignKey(User, null=True, blank=True)
class Meta:
verbose_name_plural = "Ingredients"
def __unicode__(self):
return self.name
class Food(models.Model):
name = models.CharField(max_length=30)
ingredients = models.ManyToManyField(Ingredience)
html_id = models.CharField(max_length=30, null=True, blank=True)
user = models.ForeignKey(User, null=True, blank=True)
class Meta:
verbose_name_plural = "Foods"
def __unicode__(self):
return self.name
You can use backwards relationships.
{% for item in ingrcat %}
<h2>{{ item.name }}</h2>
<ul>
{% for ingr in item.ingredience_set.all %}
<li>{{ ingr.name }}</li>
{% endfor %}
</ul>
{% endfor %}
See documentation:
https://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward
Do get_queryset on obj.manytomanyfield
{% for item in ingrcat %}
<h2>{{ item.name }}</h2>
<ul>
{% for ingr in item.ingredients.get_queryset %}
<li>{{ ingr.name }}</li>
{% endfor %}
</ul>
{% endfor %}