I have a Deviz model that inherits from MPTTmodel. I populated the database with data but can't get to show the children.
The tree should be like this:
Chapter 1
-Subchapter 1
--SubSubchapter 1
---Article 1
---Article 2
---Article 3
Chapter 2
-Subsubchapter1
--Article 1
--Article 2
In the template, it only displays the Chapters.
When changing object_list to object_list.get_descendants, it does not display the first level tree (Chapters)
models.py
class Lucrare(models.Model):
name = models.CharField(default='',max_length=100,verbose_name="Denumire")
class Deviz(MPTTModel):
lucrare = models.ForeignKey(Lucrare, on_delete=models.CASCADE,default='',null=True,related_name="deviz")
parent = TreeForeignKey('self', on_delete=models.CASCADE,null=True,blank=True,related_name='children')
cod = models.CharField(default='', max_length=20,verbose_name="Cod")
norma = models.CharField(default='',max_length=20,verbose_name="Norma")
denumire = models.TextField(default='',verbose_name="Denumire")
um_articol = models.TextField(default='',verbose_name="Um")
oferta = models.FloatField(default=0,verbose_name="Cant Oferta")
buget = models.FloatField(default=0)
cost = models.FloatField(default=0)
def __str__(self):
return self.denumire
class Meta:
verbose_name = 'Deviz'
verbose_name_plural = 'Devize'
views.py
class LucrareDetail(LoginRequiredMixin, DetailView):
template_name = "proiecte/lucrare_detail.html"
context_object_name = "lucrari"
model = Lucrare
template.html
{% recursetree object_list %}
<li>
{{ node.denumire }}
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
Related
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 %}
I can't get the cat name and kitten type from the Cat and Kitten models into the template.
This is my model.py
class Cat(models.Model):
cat_name = models.CharField(max_length=200)
def __str__(self):
return self.cat_name
class Kitten(models.Model):
cat = models.ForeignKey(Cat, on_delete=models.CASCADE, related_name='kittens')
kitten_type = models.CharField(max_length=200)
def __str__(self):
return self.kitten_type
My views.py
class CatViews(generic.ListView):
model = Cat
template_name = 'polls/cats.html'
class CatDetail(generic.DetailView):
model = Kitten
template_name = 'polls/kitten.html'
My urls.py
urlpatterns = [
path('cats/', views.CatViews.as_view(), name='catlist'),
path('cats/<int:pk>/', views.CatDetail.as_view(), name='catdetail'),
]
And finally, polls/kitten.html
<h3>{{cat.cat_name}}</h3>
{% for kitty in cat.kittens.all %}
<p>{{ kitty.kitten_type }}</p>
{% endfor %}
The url is working, I'm just not able to display the fields from the models into their respective html elements. What am I missing?
Figured it out. I had to set the CatDetailView to the Cat model, not Kitten model.
The final code:
class CatDetail(generic.DetailView):
model = Cat
template_name = 'polls/kitten.html'
class CatViews(generic.ListView):
model = Cat
template_name = 'polls/cats.html'
context_object_name='cat'
And your polls/cats.html would be like,
<h3>{{cat.cat_name}}</h3>
{% for kitty in cat.kittens.all %}
<p>{{ kitty.kitten_type }}</p>
{% endfor %}
Alter you views.py with the following
class CatViews(generic.ListView):
model = Cat
context_object_name = 'cat'
template_name = 'polls/cats.html'
Alter your polls/kitten.html
<h3>{{cat.cat_name}}</h3>
{% for kitty in cat.kittens.all %}
<p>{{ kitty.kitten_type }}</p>
{% endfor %}
EDIT
Additionally, alter you CatDetail
class CatDetail(generic.DetailView):
model = Kitten
context_object_name = 'kittens'
template_name = 'polls/kitten.html'
EDIT 2
Alter your polls/kitten.html to this.
<h3>{{cat.cat_name}}</h3>
{% for kitty in cat.catdetail.all %}
<p>{{ kitty.kitten_type }}</p>
{% endfor %}
I am trying to show a list of items organized by their category, with their respective category name directly above it in bold. For example:
Category 1
List item 1
List item 2
Category 2
List item 3
However, here is what the code currently does:
Category 1
List item 1
List item 2
List item 3
Category 2
List item 1
List item 2
List item 3
The two model classes involved taken from /models.py:
class Model(models.Model):
model_number = models.CharField('Model Number', max_length = 50)
manufacturer = models.ForeignKey('Manufacturer', on_delete = models.SET_NULL, null = True)
category = models.ForeignKey('Category', on_delete = models.SET_NULL, null = True)
description = models.TextField(max_length = 1000, help_text = "Enter brief description of product", null = True) #TextField for longer descriptions
def __str__(self):
return f'{self.model_number}..........{self.description}'
def get_absolute_url(self):
#Returns the url to access a particular location instance
return reverse('model-detail', args=[str(self.id)])
class Category(models.Model):
category = models.CharField('Equipment Type', max_length = 50,
help_text = "Enter general category of equipment")
class Meta:
verbose_name_plural = "categories" #default would have shown as "Categorys" on admin page
def __str__(self):
return self.category
/model_list.html
{% extends "base_generic.html" %}
{% block content %}
<div style="margin-left:20px; margin-top:20px">
<h1>Model list</h1>
</div>
{% if model_list %}
{% for category in model_list %}
<li><strong>{{ category.category }}</strong></li>
<ul>
{% for model in model_list %}
<li>
{{ model.model_number }}..........{{ model.description }}
</li>
{% endfor %}
</ul>
{% endfor %}
{% else %}
<p>There is no equipment in the database</p>
{% endif %}
{% endblock %}
For ForeignKey fields you can access one "Model"'s attributes from another's:
{% for model in models %}
{{ model.category.category }}
{{ model.category.help_text }}
{% endfor %}
Essentially - think of the field's for manufacturer and category that you have above in your Model as fields that are storing objects - once you get that field - your variable isn't a string or a integer, but it's an instance of the Category model. Then you can begin to select the attributes for that model, that is to say model.category is an instance of the Category object.
It looks like, from the way you have organised your models, that what you want to achieve is a little tricky. I would maybe advise looking at folding your categorisation of all your models in an array of objects of objects:
in views.py:
models = [ { 'category': 'categoryName', 'objects': [ SomeModelInstance1 , ... ] } ]
Then:
{% for model in models %}
model.category
{% for object in model.objects.all %}
{{ object.name }}
{% endfor %}
{% endfor %}
Let me know if this points you in the right direction...happy to help in the comments.
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 %}
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 %}