Cannot Get Menu item to Template - python

i have 2 apps in Django Project one is Saas and seccond one is Menu.
from Saas i can get everything to template but from Menu i cannot get menu items in html navbar.
my project Tree is
Code in Html Template
{% for item in Menu_list %}
<li class="nav-item dropdown dropdown__megamenu">
<a class="nav-link dropdown-opener" href="#">
{{ item.title }}
</a>
<div class="custom-dropdown-menu custom-megamenu">
<div class="content">
<ul class="megamenu">
menu
</ul>
</div>
</div>
</li>
{% endfor %}
Code for Views.Py
from django.shortcuts import render
from .models import Menu,MenuItem
def index(request):
Menu_list = Menu.objects.all()
MenuItem_list = MenuItem.objects.all()
return render(request, 'header-footer.html',{'Menu_list' : Menu_list,
'MenuItem_list': MenuItem_list,}
)
this is my models in admin panel everything works fine and i cant add menu and sub menu item just cannot get it from database.or in django can i geT fro database without views?
My models
from django.db import models
class Menu(models.Model):
name = models.CharField(
(u'Name'),
max_length=100
)
slug = models.SlugField(
(u'Slug')
)
base_url = models.CharField(
(u'Base URL'),
max_length=100,
blank=True,
null=True
)
description = models.TextField(
(u'Description'),
blank=True,
null=True
)
class Meta:
verbose_name = (u'menu')
verbose_name_plural = (u'menus')
def __unicode__(self):
return u"%s" % self.name
def __str__(self):
return self.__unicode__()
def save(self, *args, **kwargs):
"""
Re-order all items from 10 upwards, at intervals of 10.
This makes it easy to insert new items in the middle of
existing items without having to manually shuffle
them all around.
"""
super(Menu, self).save(*args, **kwargs)
current = 10
for item in MenuItem.objects.filter(menu=self).order_by('order'):
item.order = current
item.save()
current += 10
class MenuItem(models.Model):
menu = models.ForeignKey(
Menu,
verbose_name=(u'Name'),
on_delete=models.CASCADE,
)
order = models.IntegerField(
(u'Order'),
default=500
)
link_url = models.CharField(
(u'Link URL'),
max_length=100,
help_text=(u'URL or URI to the content, eg /about/ or http://test.com/')
)
title = models.CharField(
(u'Title'),
max_length=100
)
login_required = models.BooleanField(
(u'Login required'),
blank=True,
default=False,
help_text=(u'Should this item only be shown to authenticated users?')
)
anonymous_only = models.BooleanField(
(u'Anonymous only'),
blank=True,
default=False,
help_text=(u'Should this item only be shown to non-logged-in users?')
)
class Meta:
verbose_name = (u'menu item')
verbose_name_plural = (u'menu items')
def __unicode__(self):
return u"%s %s. %s" % (self.menu.slug, self.order, self.title)

You can list all MenuItem using the reverse relationship:
{% for item in menu_list %}
<li>
<a href="#">
{{ item.title }}
</a>
<ul>
{% for subitem in item.menuitem_set.all %}
<li>
<a href="">
{{ subitem.title }}
</a>
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
Bear in mind this will introduce a new query for every menu you have, so you should use prefetch_related in your QuerySet. You should also use related_name in your models to make the reverse relationship more readable:
class MenuItem(models.Model):
menu = models.ForeignKey(Menu, related_name="items", ...)
def index(request):
menu_list = Menu.objects.prefetch_related("items").all()
return render(request, 'header-footer.html',{'menu_list' : menu_list})

You are derived Menu_list using Menu.objects.all(). And in menu model there are no any type of title field which are you want to use in template as item.title. So, it will give you nothing because there are no any type pf 'title'
field in Menu list.

Related

Page rendering with model.py but not working after data is added in the models through admin portal

I am working on MDN Django tutorial on LocalLibrary.
I am using get_absolute_url to render generic ListView and DetailView page.
App is rendering page with else statement i.e. There are no books in the library.
But when I add books in the library through admin portal in my models. Same pages are not rendering and reflecting below error
NoReverseMatch at /catalog/books/
Reverse for 'book-detail' not found. 'book-detail' is not a valid view function or pattern name.
Please find the models.py as follows
import uuid # Required for unique book instances
from django.db import models
# Create your models here.
# Used to generate URLs by reversing the URL patterns
from django.urls import reverse
class Genre(models.Model):
"""Model representing a book genre."""
name = models.CharField(
max_length=200, help_text='Enter a book genre (e.g. Science Fiction)')
def __str__(self):
"""String for representing the Model object."""
return self.name
class Language(models.Model):
name = models.CharField(max_length=200, help_text='Enter a book language(e.g. English)')
def __str__(self):
return self.name
class Book(models.Model):
"""Model representing a book (but not a specific copy of a book)."""
title = models.CharField(max_length=200)
# Foreign Key used because book can only have one author, but authors can have multiple books
# Author as a string rather than object because it hasn't been declared yet in the file
author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
summary = models.TextField(
max_length=1000, help_text='Enter a brief description of the book')
isbn = models.CharField('ISBN', max_length=13, unique=True,
help_text='13 Character ISBN number')
# ManyToManyField used because genre can contain many books. Books can cover many genres.
# Genre class has already been defined so we can specify the object above.
genre = models.ManyToManyField(
Genre, help_text='Select a genre for this book')
language = models.ManyToManyField(
Language, help_text='Select Language for this book')
def __str__(self):
"""String for representing the Model object."""
return self.title
def get_absolute_url(self):
"""Returns the url to access a detail record for this book."""
return reverse('book-detail', kwargs= {'pk': str(self.id)})
def display_genre(self):
"""Create a string for the Genre. This is required to display genre in Admin."""
return ', '.join(genre.name for genre in self.genre.all()[:3])
display_genre.short_description = 'Genre'
def get_language(self):
"""Create a string for the Genre. This is required to display genre in Admin."""
return ', '.join(language.name for language in self.language.all()[:3])
get_language.short_description = 'Language'
class BookInstance(models.Model):
"""Model representing a specific copy of a book (i.e. that can be borrowed from the library)."""
id = models.UUIDField(primary_key=True, default=uuid.uuid4,
help_text='Unique ID for this particular book across whole library')
book = models.ForeignKey('Book', on_delete=models.RESTRICT, null=True)
imprint = models.IntegerField()
due_back = models.DateField(null=True, blank=True)
LOAN_STATUS = (
('m', 'Maintenance'),
('o', 'On loan'),
('a', 'Available'),
('r', 'Reserved'),
)
status = models.CharField(
max_length=1,
choices=LOAN_STATUS,
blank=True,
default='m',
help_text='Book availability',
)
class Meta:
ordering = ['due_back']
def __str__(self):
"""String for representing the Model object."""
return f'{self.id} ({self.book.title})'
class Author(models.Model):
"""Model representing an author."""
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField(null=True, blank=True)
date_of_death = models.DateField('Died', null=True, blank=True)
class Meta:
ordering = ['last_name', 'first_name']
def get_absolute_url(self):
from django.urls import reverse
"""Returns the url to access a particular author instance."""
return reverse('author-detail', args=[str(self.id)])
def __str__(self):
"""String for representing the Model object."""
return f'{self.last_name}, {self.first_name}'
Attached is the urls.py
from django.urls import path
from catalog import views
from catalog.views import BookListView, BookDetailView
app_name = 'catalog'
urlpatterns = [
path('', views.index, name='index'),
path('books/', views.BookListView.as_view(), name='books'),
path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),
path('authors/', views.AuthorListView.as_view(), name='authors'),
path('author/<int:pk>', views.AuthorDetailView.as_view(), name='author-detail'),
]
Views.py
from django.shortcuts import get_object_or_404
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from django.http import HttpResponse
from django.shortcuts import render
from catalog.models import *
def index(request):
num_books = Book.objects.all().count()
num_instances = BookInstance.objects.all().count()
num_genre = Genre.objects.all()
num_instances_available = BookInstance.objects.filter(status__exact='avail').count()
num_authors = Author.objects.count()
context = {
'num_books': num_books,
'num_instances': num_instances,
'num_instances_available': num_instances_available,
'num_authors': num_authors,
'num_genre': num_genre,
}
return render(request, 'catalog/index.html', context=context)
class BookListView(ListView):
model = Book
paginate_by = 2
class BookDetailView(DetailView):
model = Book
class AuthorListView(ListView):
model = Author
class AuthorDetailView(DetailView):
model = Author
Template of book_list.html
This is saved as per this method
catalog/templates/catalog/book_list.html
{% extends "catalog/base.html" %}
{% block title %}
<title>List of Books</title>
{% endblock %}
{% block content %}
<h1>Book List</h1>
{% if book_list %}
<ul>
{% for book in book_list %}
<li>
{{ book.title }}
({{ book.author }})
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no books in the library.</p>
{% endif %}
{% endblock %}
book_detail.html
This is saved as per this method
catalog/templates/catalog/book_detail.html
{% block content %}
<h1>Title: {{ book.title }}</h1>
<p><strong>Author:</strong> {{ book.author }}</p>
<p><strong>Summary:</strong> {{ book.summary }}</p>
<p><strong>ISBN:</strong> {{ book.isbn }}</p>
<p><strong>Language:</strong> {{ book.language }}</p>
<p><strong>Genre:</strong> {{ book.genre.all|join:", " }}</p>
<div style="margin-left:20px;margin-top:20px">
<h4>Copies</h4>
{% for copy in book.bookinstance_set.all %}
<hr>
<p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'd' %}text-danger{% else %}text-warning{% endif %}">{{ copy.get_status_display }}</p>
{% if copy.status != 'a' %}<p><strong>Due to be returned:</strong> {{copy.due_back}}</p>{% endif %}
<p><strong>Imprint:</strong> {{copy.imprint}}</p>
<p class="text-muted"><strong>Id:</strong> {{copy.id}}</p>
{% endfor %}
</div>
{% endblock %}```
I also find error on the same page for bootstrap link which is getting extended from base file and working fine with index.html
whereas on books.html page
It is showing this error
In template /Users/rishipalsingh/Projects/notes/mdndjango/mdn/catalog/templates/catalog/base.html, error at line 7
base.html
```
Thank you
You have namespaced your urls by writing:
app_name = 'catalog'
Hence reverse('book-detail', ...) will not work and you need to specify the namespace along with the url name, hence it should be:
reverse('catalog:book-detail', kwargs= {'pk': str(self.id)})
Similarly for the author:
reverse('catalog:author-detail', args=[str(self.id)])

Error : Select a valid choice. That choice is not one of the available choices

I am creating a blog using Django. I want my author to be auto-selected in the author's box. Actually the box is getting correctly filled by javascript but when I submit the form it shows "Select a valid choice. That choice is not one of the available choices." But I have provided it a TextInput Field. It works well when instead of TextInput, Select is provided to the author. But I don't want to let the author select I want it to get filled by the first_name who is logged in.
I want to update my choice list automatically when a new category is added on the form without shutting the whole server down and then run it again.
Forms.py
from django import forms
from .models import Post, Category
from django.contrib.auth.models import User
# choices = [('coding','coding'),('entertainment','entertainment'),('sports','ssports')]
choices = Category.objects.all().values_list('name','name')
choice_list = []
for item in choices:
choice_list.append(item)
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'title_tag','author','category', 'body', 'snippet')
widgets = {
'title': forms.TextInput(attrs={'class':'form-control'}),
'title_tag': forms.TextInput(attrs={'class':'form-control'}),
'author': forms.TextInput(attrs={'class':'form-control',
'id':'gauname','value':'','type':'hidden'}),
# 'author': forms.Select(attrs={'class':'form-control'}),
'category': forms.Select(choices=choice_list,attrs={'class':'form-control'}),
'body': forms.Textarea(attrs={'class':'form-control'}),
'snippet': forms.Textarea(attrs={'class':'form-control'}),
}
views.py
class AddCategoryView(CreateView):
model = Category
form_class = AddCategory
template_name = 'add_category.html'
# fields = '__all__'
models.py
class Post(models.Model):
title = models.CharField(max_length=255)
title_tag = models.CharField(max_length=255)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
# body = models.TextField()
body = RichTextField(blank=True, null=True)
post_date = models.DateTimeField(default=datetime.now)
category = models.CharField(max_length=255, default='coding')
snippet = models.CharField(max_length=255)
likes = models.ManyToManyField(User, related_name='blog_posts')
def total_likes(self):
return self.likes.count()
def __str__(self):
return self.title + '|' + str(self.author)
def get_absolute_url(self):
# return reverse('article-detail', args=(str(self.id)))
return reverse('home')
HTML
{% block content %}
{% if user.is_authenticated %}
<h1>Add Post...</h1>
<br><br><br>
<form method="POST">
<div class="form-group">
{% csrf_token %}
{{form.media}}
{{form.as_p}}
<!-- <input class = form-control type="text" id="gauname" name="author" value=""> -->
<button class="btn btn-secondary" name="button">Post</button>
</div>
</form>
<script>
var name = "{{ request.user.first_name }}";
document.getElementById("gauname").value = name;
</script>
{% else %}
You are not allowed here!
{% endif %}
{% end block %}
UPDATE
forms.py
class AddCategory(forms.ModelForm):
class Meta:
model = Category
fields = ('name',)
widgets = {
'name': forms.TextInput(attrs={'class':'form-control'}),
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["name"] = forms.ModelChoiceField(
queryset=Category.objects.all(),
)
I want to update my choice list automatically when a new category is added on the form without shutting the whole server down and then run it again.
If there are two people with the same first name, how is Django supposed to know who is the user here? In other words, how can Django map the first name to a user? It doesn't make sense
Since it's a hidden field anyway, instead of request.user.first_name you can just pass request.user.pk instead (The Unique ID of that particular user)

how do i link my listview and detailsview in django templates such that when i click the list it then shows me the details

"im setting up my django-templates of a project o show schoolevents and job listings, i want its response to show me details of a list once i click the item on the list -can some one help am a newbie tp programming"
i've tried adding slugfield to my models, changed the urls a couple of time but still i'm failing to reach my target
models.py
class Events(models.Model):
title = models.CharField(max_length=80)
host = models.CharField(max_length=80)
venue = models.CharField(max_length=80)
event_image = models.ImageField()
details = models.TextField()
posted_at = models.DateTimeField(auto_now_add=True)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
contacts = models.CharField(max_length=80)
sponsors = models.CharField(max_length=80, null=True, blank=True)
slug = models.SlugField(max_length=150, null=True, blank=True)
class Meta:
ordering = ('-posted_at',)
views.py
class EventsListView(ListView):
model = Events
form_class = EventsForm
context_object_name = 'all_events'
template_name = 'events_list.html'
success_url = reverse_lazy('list_events')
def get_queryset(self):
qs = super(EventsListView, self).get_queryset()
return qs
class DetailEventsView(DetailView):
model = Events
def render_to_response(self, context, **response_kwargs):
if self.request.is_ajax():
return JsonResponse('Your comment has been uploaded!',safe=False, **response_kwargs)
else:
return super(DetailView,self).render_to_response(context, **response_kwargs)
def get_context_data(self, **kwargs):
context = super(Events, self).get_context_data(**kwargs)
data = self.kwargs['name']
context['object'] = Events.objects.filter(events_id=data)
return context
url.py
urlpatterns = [
url(r'^create-events/$', CreateEventsView.as_view(),
name='create_events'),
url(r'^list-events/$', EventsListView.as_view(),
name='list_events'),
url(r'^(?P<events_id>\d+)$', DetailEventsView.as_view(),
name='detail_events'),
]
templates
<div>
{% for events in all_events %}
<li>
<a href="{% url 'posts:list_events' %}"> {{ events.title }}
</a>
</li>
<a href="{% url 'posts:detail_events' %}" class="btn btn-default">
{% trans '{{ events.title }}' %}</a>
{% endfor %}
</div>
Reverse for 'detail_events' with no arguments not found. 1 pattern(s) tried: ['(?P<events_id>\\d+)$']
well i figured it a long time but just to help newbies like me,the problem was the templates ,in the part which events_list links to the event_details it was like
<a href="{% url 'posts:detail_events' %}" class="btn btn-default">
but it should be this way
{% trans '{{ events.title }}' %}
and for details it can be like
<h1 class="mt-4 text-center">{{ events.title }}</h1>
host : <p>{{ events.host }}</p>
......

How can I filter and count objects in DJANGO template?

Hello I justa want to ask this because Im new in django, my trouble is that i want to count how many comments have a post and put it in to the html template.
But the thing is that im using for to gather all the events in the db, but i just want to show only the count of comments that have every event that the "for" are showing.
this is my models, view, and template.
Thank you so much.
MODELS
class Event(TimeStampModel):
name = models.CharField(max_length=200, unique=True)
slug = models.SlugField(editable=False)
summary = models.TextField(max_length=255)
content = models.TextField()
category = models.ForeignKey(Category)
place = models.CharField(max_length=50)
start = models.DateTimeField()
finish = models.DateTimeField()
image = models.ImageField(upload_to = 'eventos')
is_free = models.BooleanField(default=True)
amount = models.DecimalField(max_digits=6, decimal_places=0, default=0)
views = models.PositiveIntegerField(default=0)
organizer = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.name)
super(Event, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
class Comments(TimeStampModel):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
event = models.ForeignKey(Event)
content = models.TextField()
def __unicode__(self):
return "%s %s" % (self.user.username, self.event.name)
VIEW
class IndexView(TemplateView):
template_name = 'eventos/index.html'
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['events'] = Event.objects.all().order_by('-created')[:6]
context['categories'] = Category.objects.all()
context['comments'] = Comments.objects.all()
return context
HTML TEMPLATE
{% for event in events %}
<li class="span4 ">
<div class="thumbnail thumbnail-1">
<h3 class="titulo-fix" >{{ event.name }}</h3>
<img class="center-cropped" src="{{ event.image.url }}" alt="">
<section>
<h3>{{ event.category }} </h3>
<div class="meta">
<time datetime="2012-11-09" class="date-1"><i class="icon-calendar"></i> {{ event.start }}</time>
<div class="name-author"><i class="icon-user"></i> {{ event.organizer }}</div>
<i class="icon-comment"></i> comments
</div>
<div class="clear"></div>
<p>{{ event.place }}</p>
Leer mas..
</section>
</div>
</li>
{% endfor %}
I want to show it just in that part of the html where it says comments.. with a tag of course, but i just dont know wich tag or how to do it.
You can create a helper method on the model which can help you show the number of comments.
Something like this:
class Event(TimeStampModel):
...
def comments_count(self):
#Your filter criteria can go here.
return self.comments_set.count()
and in the comments:
{{event.comments_count}}
More documentation on the reverse lookups can be found here
If you are not filtering, as, #MadWombat mentions, you could just do
{{event.comments_set.count}}

How to use django formsets to do a questionnaire

I'm doing an application and now I need to make an evaluation that users can take, my problem is that I want to use a formset to list the questions with respective choices, I know this can be done with using formsets but not the way to get it done. Following is my code:
# models.py
class Evaluation(models.Model):
"""
An evaluation is for a session.
Each session should have an evaluation
"""
session = models.OneToOneField(
Session,
related_name='evaluation',
verbose_name=u'Sesión'
)
class Meta:
verbose_name = u'Evaluación'
verbose_name_plural = u'Evaluaciones'
def __unicode__(self):
return u'Evaluación de la sesion {0}'.format(
self.session.name
)
class Question(models.Model):
"""
A question inside of an evaluation
"""
evaluation = models.ForeignKey(
Evaluation,
verbose_name=u'Evaluación',
related_name='questions'
)
question_type = models.CharField(
max_length=20,
verbose_name=u'Tipo de respuesta',
choices=QUESTION_TYPES
)
sentence = models.CharField(
max_length=255,
verbose_name=u'Pregunta'
)
position = models.IntegerField(
default=0,
verbose_name=u'Posición'
)
class Meta:
verbose_name = u'Pregunta'
verbose_name_plural = u'Preguntas'
ordering = ['position', 'sentence']
def __unicode__(self):
return self.sentence
class Choice(models.Model):
question = models.ForeignKey(
Question,
related_name='choices',
verbose_name=u'Pregunta'
)
sentence = models.CharField(
max_length=255,
verbose_name=u'Posible respuesta'
)
position = models.IntegerField(
default=0,
verbose_name=u'Posición'
)
class Meta:
verbose_name = u'Posible respuesta'
verbose_name_plural = u'Posibles respuestas'
ordering = ['position', 'sentence']
def __unicode__(self):
return self.sentence
----
# forms.py
from django.forms.models import inlineformset_factory
from models import Evaluation, Question
AnswerFormSet = inlineformset_factory(
Evaluation, Question, exclude=('question',),
extra=0, can_delete=False
)
----
# views.py
#login_required()
def session_evaluation(request, course_slug, session_position):
data = {}
course = get_object_or_404(Course, slug=course_slug)
session = Session.objects.filter(course=course).get(position=session_position)
evaluation = get_object_or_404(Evaluation, session=session)
if request.method == 'POST':
formset = AnswerFormSet(request.POST, instance=evaluation)
if formset.is_valid():
formset.save()
print 'formset valid...'
else:
formset = AnswerFormSet(instance=evaluation)
data['course'] = course
data['session'] = session
data['formset'] = formset
return render(request, 'courses/session_evaluation.html', data)
----
# template.html
<form id="evaluation" method="post" role="form">
{% csrf_token %}
{{ formset.management_form }}
<ul class="evaluation">
{% for form in formset.forms %}
<li>
{{ form.instance }}
{{ form.instance.choices.all }}
</li>
{% endfor %}
</ul>
<div class="form-group clearfix nmb">
<button type="submit" class="btn btn-primary pull-right">Enviar respuestas</button>
</div>
</form>
As you can see I have the models well written but from the forms all the code is only an experiment and I really don't know the way to do it.
What I'm getting in the template with this code is the question sentence and the list of choices, something like:
[question sentence here]? [<Choice: [choice #1 here]>, <Choice: [choice #2 here]>]
What is the clean and easy way to do it with formsets?
What I want to get is a list of questions with the respective list of choices with radio buttons because this is an evaluation.
Should not it be {{ form.as_p }} or {{ form.as_table }}? The instance is already created in the view, so need not be used in the template.

Categories

Resources