How to Query DB using .object in Django - django

I have few categories. Say Electronics and Toy. and i have mutiple shops in a mall. A shop is saved with a foreign key(category). Now in the navigation bar.. i want to list stores based on their categories. Thanks in anticipation
models.py
class ShopCategories(models.Model):
category = models.CharField(max_length=50, unique=True,)
def __str__(self):
return self.category
class NewShop(models.Model):
category = models.ForeignKey(ShopCategories)
name = models.CharField(max_length=100, unique=True)
tagline = models.CharField(max_length=50, default='Enter tagline here2')
description = models.TextField(default='enter shop description')
def __str__(self):
return self.name
views.py
def basefile(request):
shop_cat = NewShop.objects.filter(category_id=1)
shop_name = NewShop.objects.filter(name=shop_cat)
return render_to_response('base.html', {'Shopname':shop_name, 'Shopcat':shop_cat})
base.html
{% for category_id in Shopcat %}
<li>{{ Shopname }}</l>
{% endfor %}

To get all store use below query.
shopcat = NewShop.objects.filter(category__category="category name")
base.html
{% for shop in shopcat %}
<li>{{ shop.name }}</l>
{% endfor %}

Try do this:
urls.py
urlpatterns = [
...
url(r'^get_shops_by_category/(?P<id_category>\d+)/$', views.get_shops_by_category, name = "get_shops_by_category"),
]
views.py
def basefile(request):
categories = ShopCategories.objects.all()
shop_name = NewShop.objects.filter(name=shop_cat)
return render_to_response('base.html', {'Shopname':shop_name, 'categories': categories})
def get_shops_by_category(request, **kwargs):
categories = ShopCategories.objects.all()
current_category = ShopCategories.objects.get(id = kwargs['id_category']
shops = NewShop.objects.filter(category = current_category)
return render_to_response('base.html', {'shops': shops, 'categories': categories, 'current_category' current_category})
base.html
...
<select>
{% for category in categories %}
{% if current_category %}
<option value="{{ category.id }}">{{ category.category }}</option>
{% else %}
<option value="{{ category.id }}" onclick="location.href = '{% url 'your_app:your_url' category.id %}'">{{ category.category }}</option>
{% endfor %}
</select>
{% if shops %}
<table>
<thead>
<tr>
<th>Shop name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for shop in shops %}
<tr>
<td>{{ shop.name }}</td>
<td><!-- Buttons or links, ect ... --></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
...

Thanks Guys. I know this isn't the best method but i was able to fix it this way
models.py
class ShopCategories(models.Model):
category = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.category
class NewShop(models.Model):
category = models.ForeignKey(ShopCategories)
name = models.CharField(max_length=100, unique=True)
tagline = models.CharField(max_length=50, default='Enter tagline here2')
description = models.TextField(default='enter shop description')
def __str__(self):
return self.name
views.py
def basefile(request):
cat1 = NewShop.objects.filter(category_id=1)
cat2 = NewShop.objects.filter(category_id=2)
cat3 = NewShop.objects.filter(category_id=3)
cat4 = NewShop.objects.filter(category_id=4)
shop_name1 = ShopCategories.objects.filter(id=1)
shop_name2 = ShopCategories.objects.filter(id=2)
shop_name3 = ShopCategories.objects.filter(id=3)
shop_name4 = ShopCategories.objects.filter(id=4)
return render_to_response('base.html', {'Shop_cat1':cat1, 'Shop_cat2':cat2, 'Shop_cat3':cat3,
'Shop_cat4':cat4,'shop_name1':shop_name1, 'shop_name2':shop_name2,
'shop_name3':shop_name3, 'shop_name4':shop_name4})
base.html
{% for shop_name1 in shop_name1 %}
<li>
<h3> {{ shop_name1 }}</h3>
</li>
{% endfor %}
{% for Shop_cat1 in Shop_cat1 %}
<li>{{ Shop_cat1 }}</li>
{% endfor %}

Related

How to slice items generated from a forloop with conditionals in django

I have a list of categories as well as a list of products my template is in such a manner that it has category sections each with a display of products that belong to said categories. I created a for loop for categories so as to easily display category sections for each category I create. I then went on to create a forloop for products within the category forloop with a condition so as to match products with their actual category before they are displayed under their category section. how can I slice the resulting products to limit the number of products shown
Models.py
class Category(models.Model):
name = models.CharField(max_length=120)
image_263x629 = models.ImageField(upload_to='cat_imgs')
image_263x629_2 = models.ImageField(upload_to='cat_imgs')
image_263x629_3 = models.ImageField(upload_to='cat_imgs')
img_array = [image_263x629, image_263x629_2, image_263x629_3]
description = models.CharField(max_length=250)
def __str__(self):
return self.name
class SubCategory(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=300)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.name
#def get_absolute_url(self):
# return reverse('subcat_detail', args=[str(self.id)])
class Product(models.Model):
name = models.CharField(max_length=120)
price = models.FloatField()
image_182x182 = models.ImageField(upload_to='pdt_imgs/')
image_1200x1200 = models.ImageField(upload_to='pdt_imgs/alt_imgs/')
image_600x600 = models.ImageField(upload_to='pdt_imgs/alt_imgs/')
image_600x600_2 = models.ImageField(upload_to='pdt_imgs/alt_imgs/')
image_300x300 = models.ImageField(upload_to='pdt_imgs/alt_imgs/')
img_array = [image_1200x1200, image_600x600, image_600x600_2]
sku = models.IntegerField()
available = models.BooleanField(default=True)
discount = models.IntegerField(default = 0)
description = models.CharField(max_length=120, blank=True, null=True)
brand = models.CharField(max_length=120, blank=True, null=True)
category = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
seller = models.ForeignKey(Seller, on_delete=models.CASCADE)
Views
class HomePageView(ListView):
model = SubCategory
template_name = 'home.html'
queryset = SubCategory.objects.all()
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
context['products'] = Product.objects.all()
context['pdts'] = Product.objects.order_by('?')[:12]
context['categories'] = Category.objects.all()
context['subcategories'] = SubCategory.objects.all()
return context
Template
{% for category in categories %}
<div class="ps-block--products-of-category">
<div class="ps-block__categories">
<h3>{{ category.name }}</h3>
<ul>
{% for subcategory in subcategories %}
{% if subcategory.category.name == category.name %}
<li>{{ subcategory.name }}</li>
{% endif %}
{% endfor %}
</ul><a class="ps-block__more-link" href="{% url 'cat_detail' category.id %}">View All</a>
</div>
<div class="ps-block__slider">
<div class="ps-carousel--product-box owl-slider" data-owl-auto="true" data-owl-loop="true"
data-owl-speed="7000" data-owl-gap="0" data-owl-nav="true" data-owl-dots="true" data-owl-item="1"
data-owl-item-xs="1" data-owl-item-sm="1" data-owl-item-md="1" data-owl-item-lg="1" data-owl-duration="500"
data-owl-mousedrag="off">
<img src="{{ category.image_263x629.url }}" alt="">
<img src="{{ category.image_263x629_2.url }}" alt="">
<img src="{{ category.image_263x629_3.url }}" alt="">
</div>
</div>
<div class="ps-block__product-box">
{% for product in products %}
{% if product.category.category.name == category.name %}
<div class="ps-product ps-product--simple">
<div class="ps-product__thumbnail"><a href="{% url 'pdt_detail' product.id %}"><img src="{{ product.image_300x300.url }}"
alt=""></a>
{% if product.discount > 0 %}
<div class="ps-product__badge">-{{ product.discount }}%</div>
{% endif %}
{% if product.available == False %}
<div class="ps-product__badge out-stock">Out Of Stock</div>
{% endif %}
</div>
<div class="ps-product__container">
<div class="ps-product__content" data-mh="clothing"><a class="ps-product__title"
href="{% url 'pdt_detail' product.id %}">{{ product.name }}</a>
<div class="ps-product__rating">
<select class="ps-rating" data-read-only="true">
<option value="1">1</option>
<option value="1">2</option>
<option value="1">3</option>
<option value="1">4</option>
<option value="2">5</option>
</select><span>01</span>
</div>
<p class="ps-product__price sale">UGX{{ product.price }}</p>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
Please do not filter in the template. You should filter in the view. A template implements rendering logic, not business logic*.
You can filter and slice in the view with:
def my_view(request):
# …
products = Product.objects.filter(category__name='specified category')[:10]
context = {
'products': products
}
return render(request, 'my_template.html', context)
This is not only the place where filtering belongs, it is also more efficient since we here will filter and slice on the database side. Typically a database can do this more efficient, and it furthermore limits the bandwidth from the database to the Django/Python layer.
Note (based on #SLDem's comment):
If you aim to filter children, you make use of a Prefetch object [Django-doc]. Indeed, imagine that we have a QuerySet of Categorys and we want to only retain Products that are available, we can use:
from django.db.models import Prefetch
categories = Category.objects.prefetch_related(
Prefetch(
'product_set',
Product.objects.filter(available=True),
to_attr='available_products'
)
)
then in the template we can render this with:
{% for category in categories %}
{% for product in category.available_products %}
…
{% endfor %}
{% endfor %}

Invite Registered Users to vote in voting app

I'm trying to expand the Django tutorial for a school project and make it into a more usable voting app.
What I want is to allow users to create Polls and invite other registered users by email to vote on their Poll. Only the invited users will be allowed to vote.
My models.py:
class Poll(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published', auto_now_add=True)
is_active = models.BooleanField(default=True)
activation_date = models.DateTimeField('Activation Date', blank=True, null=True)
expiration_date = models.DateTimeField('Expiration Date', blank=True, null=True)
public_key = models.CharField(max_length=30, blank=True)
hash = models.CharField(max_length=128, blank=True)
timestamp = models.DateTimeField(auto_now=True)
def __str__(self):
return self.question_text
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
class Choice(models.Model):
question = models.ForeignKey(Poll, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
class EligibleVoters(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
email = models.EmailField(null=True)
I have a Poll table which contains the Poll Title and other information regarding the Poll. I also created a separate Choices table (like in the tutorial) which has a ForeignKey to the Poll table and contains the poll choices.
I figured that in order to invite users as eligible voters I needed a third table with ForeignKeys to the Poll and User tables. So i created one.
I should note that I'm using the build-in user model.
Here's my views.py:
class NewPoll(CreateView):
model = Poll
fields = ['question_text', 'is_active', 'activation_date', 'expiration_date']
success_url = reverse_lazy('voting:index')
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if self.request.POST:
data['choices'] = ChoiceFormSet(self.request.POST)
# data['eligible_voters_poll'] = EligibleVotersFormSetPoll(self.request.POST)
# data['eligible_voters_user'] = EligibleVotersFormSetUser(self.request.POST)
#data['eligible_voters'] = EligibleVotersFormSet(self.request.POST)
else:
data['choices'] = ChoiceFormSet()
# data['eligible_voters_poll'] = EligibleVotersFormSetPoll()
# data['eligible_voters_user'] = EligibleVotersFormSetUser()
# data['eligible_voters'] = EligibleVotersFormSet()
return data
def form_valid(self, form):
context = self.get_context_data()
choices = context['choices']
# eligible_voters_poll = context['eligible_voters_poll']
# eligible_voters_user = context['eligible_voters_user']
#eligible_voters = context['eligible_voters']
with transaction.atomic():
self.object = form.save()
if choices.is_valid():
choices.instance = self.object
choices.save()
# if eligible_voters_poll.is_valid() and eligible_voters_user.is_valid():
# eligible_voters_poll.instance = self.object
# eligible_voters_poll.save()
# eligible_voters_user.instance = self.object
# eligible_voters_user.save()
#if eligible_voters.is_valid():
# eligible_voters.instance = self.object
# eligible_voters.save()
return super().form_valid(form)
I have commented the lines that are previous attempt into making it work. Without the commented lines the user is able to create a poll and also create choices. I'm having trouble making the invite part working though.
Here is my forms.py:
class PollForm(ModelForm):
activation_date = forms.DateTimeField(required=False)
expiration_date = forms.DateTimeField(required=False)
class Meta:
model = Poll
fields = ['question_text', 'is_active', 'activation_date', 'expiration_date']
class ChoiceForm(ModelForm):
class Meta:
model = Choice
exclude = ['votes']
ChoiceFormSet = inlineformset_factory(Poll, Choice, form=ChoiceForm, extra=1)
def form_maker(parent2):
class EligibleVotersForm(ModelForm):
# def __init__(self, user, poll, *args, **kwargs):
# self.user = user
# self.poll = poll
# super().__init__(*args, **kwargs)
def save(self, commit=True):
instance = super(EligibleVotersForm, self).save(commit=False)
# instance.parent1 = parent1
instance.parent2 = parent2
if commit:
instance.save()
return instance
class Meta:
model = EligibleVoters
fields = ['email']
return EligibleVotersForm
# EligibleVotersFormSetPoll = inlineformset_factory(Poll, EligibleVoters, form=EligibleVotersForm, extra=1)
# EligibleVotersFormSetUser = inlineformset_factory(User, EligibleVoters, form=EligibleVotersForm, extra=1)
# EligibleVotersFormSet = inlineformset_factory(Poll, EligibleVoters, form=form_maker(User), extra=1)
Here I have commented out again the lines that belong to my failed attempts at making it work. The closer I got it to working is to be able to invite by any email (not just the registered ones, which is what I want) and fill the EligibleVoters table with the emails associated with the poll_id. The user_id column though remained, empty.
Here's my html file:
{% extends 'base.html' %}
{% block content %}
{% load static %}
<h2>Poll Creation</h2>
<div class="col-md-4">
<form action='' method="post">
{% csrf_token %}
{{ form.as_p }}
<table class="table">
{{ choices.management_form }}
{% for form in choices.forms %}
{% if forloop.first %}
<thead>
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<tr class="{% cycle 'row1' 'row2' %} formset_row1">
{% for field in form.visible_fields %}
<td>
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<table class="table">
{{ eligible_voters.management_form }}
{% for form in eligible_voters.forms %}
{% if forloop.first %}
<thead>
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<tr class="{% cycle 'row1' 'row2' %} formset_row2">
{% for field in form.visible_fields %}
<td>
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<input type="submit" value="Save"/> back to the list
</form>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="{% static 'voting/js/jquery.formset.js' %}"></script>
<script type="text/javascript">
$('.formset_row1').formset({
addText: 'add poll choice',
deleteText: 'remove',
prefix: 'choice_set'
});
$('.formset_row2').formset({
addText: 'add eligible voter',
deleteText: 'remove',
prefix: 'eligiblevoters_set'
});
</script>
{% endblock %}
Any ideas on how to make it work and only allow he eligible voters to vote for the polls they are invited to?
I was thinking that maybe my EligibleVoters model is wrong somehow and I need a ManyToMany field somewhere??

Display a form and the output on the same page

This code will display the form. I can input data, submit the data and the data then displays along with the previous input data from the mySQL DB table where the dat is written, but when the data displays the input form goes away (all expect the submit button that is). I've come across this subject here, but could never quite find the answer that worked for me.
**`models.py`**
class UnitPool(models.Model):
# rack = models.ForeignKey(Rack)
# platform = models.ForeignKey(Group)
location = models.CharField(max_length=10, choices=LAB, default='Choose', blank=False)
rack = models.CharField(max_length=10, choices=RACKS, default='Choose', blank=False)
platform = models.CharField(max_length=10, choices = PLATFORM, default='Choose',blank=False)
unit_HW_Serial = models.CharField(max_length=20, blank=False, null=False)
unit_SW_Serial = models.CharField(max_length=20, blank=False, null=False)
unit_SKU = models.CharField(max_length=20, blank=False, null=False)
comments = models.CharField(max_length=64, blank=True, null=True, default='')
def __unicode__(self): # __unicode__ on Python 2
return '%s %s %s %s %s %s' % (self.rack,
self.platform,
self.unit_HW_Serial,
self.unit_SW_Serial,
self.unit_SKU,
self.comments)
class UUTForm(ModelForm):
class Meta:
model = UnitPool
widgets = {
'comments': TextInput(attrs={'size': 10}),
}
fields = ['location','rack', 'platform','unit_HW_Serial','unit_SW_Serial','unit_SKU','comments']
**forms.html**
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
<div class='row'>
<div class='col-md-2'>
{% if title %}
<h1 class='{% if title_align_center %}text-align-center{% endif %}'>{{ title }}</h1>
{% endif %}
<form method='POST' action=''>{% csrf_token %}
{{ form|crispy }}
<input class='btn btn-primary' type='submit' value='Add Unit' />
</form>
</div>
</div>
</div>
{% if queryset %}
{% if rack != '' %}
<div class="container">
<div class="row">
<div class='col-md-8 col-md-offset-3'>
<h1>Unit Data Entered</h1>
<table class='table'>
<td><b>Item</b></td>
<td><b>Location</b></td>
<td><b>Rack#</b></td>
<td><b>Platform</b></td>
<td><b>HW SN</b></td>
<td><b>SW SN</b></td>
<td><b>SKU</b></td>
<td><b>Comment</b></td>
{% for instance in queryset %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ instance.location }}</td>
<td>{{ instance.rack }}</td>
<td>{{ instance.platform }}</td>
<td>{{ instance.unit_HW_Serial }}</td>
<td>{{ instance.unit_SW_Serial }}</td>
<td>{{ instance.unit_SKU }}</td>
<td>{{ instance.comments }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
{% endif %}
{% endif %}
{% endblock %}
**views.py**
from django.conf import settings
from django.shortcuts import render
from .models import UnitPool, UUTForm
def labunits(request):
title = 'Enter Info'
form = UUTForm(request.POST or None)
context = {
"title": title,
"form": form
}
if form.is_valid():
instance = form.save(commit=False)
instance.save()
queryset = UnitPool.objects.all().order_by('rack','platform')
context = {
"queryset": queryset
}
return render(request, "labunits/forms.html", context)
You need to pass the form in the context after calling .is_valid() as #Daniel also mentioned.
Since you are not passing the form in the context again after calling the .is_valid() function, the form does not get displayed again in the template.
So, when you are resetting the context, you need to pass the form also.
def labunits(request):
title = 'Enter Info'
form = UUTForm(request.POST or None)
context = {
"title": title,
"form": form
}
if form.is_valid():
instance = form.save(commit=False)
instance.save()
queryset = UnitPool.objects.all().order_by('rack','platform')
context = {
"queryset": queryset,
"form" : form # pass the form in the context
}
return render(request, "labunits/forms.html", context)

Django model cross reference in templatre

Ok So my mind is going to mush...
I have 2 models. One is a card location and the other holds card types. I've got a view and template which display's the cards in a specific chassis. What I can't seem to get to work is the foreign key reference. I want to display the CardType.sName in the template.
I'm certain i've just done something stupid ...
Models.py:
class CardLocation(models.Model):
chassis = models.ForeignKey(Chassis)
slot = models.CharField(max_length=20)
slot_sub = models.CharField(max_length=20)
CardType = models.ForeignKey(CardType)
PartNum = models.CharField(max_length=200)
ProdID = models.CharField(max_length=200)
versID = models.CharField(max_length=200)
serialNum = models.CharField(max_length=200)
cleiCode = models.CharField(max_length=200)
lastSeen = models.DateTimeField()
isActive = models.BooleanField(default=0)
def __unicode__(self):
return self.slot
class CardType(models.Model):
sName = models.CharField(max_length=5)
lName = models.CharField(max_length=200)
description = models.CharField(max_length=200)
def __unicode__(self):
return self.sName
views.py
class DetailView(generic.ListView):
model = CardLocation
template_name = 'chassis/detail.html'
context_object_name = 'cardLoc'
def get_queryset(self):
#chassis_id = get_object_or_404(CardLocation, chassis_id__iexact=self.args[0])
chassis_id = self.args[0]
return CardLocation.objects.filter(chassis_id=chassis_id)
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(DetailView, self).get_context_data(**kwargs)
# Add in the
context['chassisQ'] = Chassis.objects.get(id=self.args[0])
#context['CardType'] = CardType.objects.order_by()
return context
detail.html
{% load staticfiles %}
<h2>
<table>
<tr><td>Name:</td><td>{{ chassisQ.name }}<td></tr>
<tr><td>Owner:</td><td>{{ chassisQ.owner }}<td></tr>
<tr><td>ip Adress:</td><td>{{ chassisQ.ipAddr }}<td></tr>
<tr><td>Last updated:</td><td>{{ chassisQ.lastSeen }}<td></tr>
</table>
</h2>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% if cardLoc %}
<table border=1>
<tr><td>slot</td><td>Type</td><td>Part Number</td><td>Product ID/</td><td>Version ID</td><td>Serial Num</td><td>CLEI code</td></tr>
{% for card in cardLoc %}
<tr>
<td align="right">{{ card.slot }}</td>
<td>Type {{ card.cardtype__set.all.sName }} </td> <!-- DISPLAY sName HERE -->
<td>{{ card.PartNum }}</td>
<td align="right">{{ card.ProdID }}/</td>
<td align="left">{{ card.versID }}</td>
<td>{{ card.serialNum }}</td>
<td>{{ card.cleiCode }}</td>
</tr>
{% endfor %}
</table>
{% else %}
<p>No cards are available...</p>
{% endif %}
A Card has numerous CardTypes (as it's a ForeignKey relationship), not just one. You have:
<td>Type {{ card.cardtype__set.all.sName }} </td>
You need to loop through all the CardTypes related to the Card:
{% for card in cardLoc %}
...
{% for cardtype in card.cardtype__set.all %}
<td>Type {{ cardtype.sName }}</td>
{% endfor %}
...
{% endfor %}

Django Query For most liked

I'm been trying to figure out how could I query forthe most liked whiteboard for a particular category
At the moment i'm been querying for all the whiteboards objects for a particular category.
One of my solutions was to query by the boards by the counts of liked but I just couldn't think of a way to query for it
An example at the moment I can retrieve all the whiteboard objects for a particular category , Now how could I retrieve the most liked whiteboard for a particular category.
Can someone help me create function that would query the most liked board of the category so I can understand logically how I can create my own later .Thank you
class WhiteBoard(models.Model):
ENGLISH = 'ENGLISH'
MATH = 'MATH'
SCIENCE = 'SCIENCE'
BIOLOGY = 'BIOLOGY'
CATEGORY = (
(ENGLISH , 'English'),
(MATH, 'Math'),
(SCIENCE, 'Science'),
(BIOLOGY, 'Biology'),
)
Category =models.CharField(max_length=30,choices=CATEGORY)
user = models.ForeignKey(User)
name = models.CharField(max_length=100)
picture = models.OneToOneField('Picture',related_name='picture',blank=True,null=True)
def __unicode__(self):
return self.name
class LikeBoard(models.Model):
user = models.ForeignKey(User)
Whiteboard = models.ForeignKey(WhiteBoard)
created = models.DateTimeField(auto_now_add=True)
My views.py
def WhiteBoardFinder(request):
form = WhiteBoardFinderForm(request.POST)
fo = WhiteBoardFinderForm()
if form.is_valid():
Category = form.cleaned_data['Category']
Whiteboard = WhiteBoard.objects.filter(Category=Category)
return render(request,"boardfinder.html",{"board":board,"fo":fo})
return render(request,"boardfinder.html",{"fo":fo})
boardfinder.html
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ fo.as_p }}
<input type = "submit" value= "Find Board" />
</form>
{% if board %}
<ul>
{% for b in board %}
<li><a href ="{% url world:Boat b.id %}">{{ b.name }}</li>
{% if b.picture %}
<br><img src="{{ b.picture.image.url }}">
{% endif %}
{% endfor %}
</ul>
{% endif %}
My forms.py
class BoardFinderForm(forms.ModelForm):
class Meta:
model = WhiteBoard
fields = ('Category',)
models.py
class WhiteBoard(models.Model):
ENGLISH = 'ENGLISH'
MATH = 'MATH'
SCIENCE = 'SCIENCE'
BIOLOGY = 'BIOLOGY'
CATEGORY = (
(ENGLISH , 'English'),
(MATH, 'Math'),
(SCIENCE, 'Science'),
(BIOLOGY, 'Biology'),
)
Category =models.CharField(max_length=30,choices=CATEGORY)
user = models.ForeignKey(User)
name = models.CharField(max_length=100)
picture = models.OneToOneField('Picture',related_name='picture',blank=True,null=True)
def __unicode__(self):
return self.name
#property
def count_likes(self):
return LikeBoard.objects.filter(whiteboard=self).count()
class LikeBoard(models.Model):
user = models.ForeignKey(User)
whiteboard = models.ForeignKey(WhiteBoard) //modified because of conflict
created = models.DateTimeField(auto_now_add=True)
views.py
def WhiteBoardFinder(request):
form = WhiteBoardFinderForm(request.POST)
fo = WhiteBoardFinderForm()
if form.is_valid():
Category = form.cleaned_data['Category']
whiteboard = WhiteBoard.objects.filter(Category=Category)
categories = WhiteBoard.objects.values_list('Category', flat=True).distinct()
whites = sorted(whiteboard, key=lambda x: x.count_likes, reverse=True)
return render(request,"boardfinder.html",{
"board":board,"fo":fo, "categories": categories, "whites": whites})
return render(request,"boardfinder.html",{"fo":fo})
templates
{% for category in categories %}
{{ category }}<br/>
{% for white in whites %}
{% if white.Category == category %}
{{ white }} - {{ white.count_likes }},
{% endif %}
{% endfor %}<br/>
{% endfor %}