I get this error TemplateDoesNotExist at /poll/poll/result.html....I think I'm pointing to poll/poll/result.html but how do I point it to poll/result.html
{'Gender': <QuerySet [{'Gender': 'female', 'Diseases': 'Malaria', 'Number': 1}, {'Gender': 'female', 'Diseases': 'cholera', 'Number': 2}
I am new to django but what possibly am I doing wrong here.This is the file structure for template.html: mysite/polls/templates/polls/template.html and for result.html its mysite/polls/templates/polls/result.html
Views.py
from django.views.generic import ListView, CreateView, UpdateView
from django.urls import reverse_lazy
from . models import MyModel
from . forms import MyModelForm
from django.db.models import Count
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.views.generic.list import ListView
class CreateMyModelView(CreateView):
model = MyModel
form_class = MyModelForm
template_name = 'poll/template.html'
success_url = 'poll/result.html'
class MyModelListView(ListView):
model = MyModel
def get_queryset(self):
queryset = MyModel.objects.values('Gender', 'Diseases').annotate(Number=Count("Gender"))
return render('poll/result.html', {'Gender': queryset})
urls.py
from django.conf.urls import url
from django.urls import path
from . import views
urlpatterns = [
url(r'^$', views.CreateMyModelView.as_view(), name='abc'),
path('poll/result.html', views.MyModelListView.as_view(), name='result'),
]
models.py
from django.db import models
Gender = (
('male', 'MALE'),
('female', 'FEMALE'),
)
Diseases = (
('cholera', 'CHOLERA'),
('hiv', 'HIV'),
('Malaria', 'MALARIA'),
('Typhoid', 'TYPHOID'),
)
class MyModel(models.Model):
Gender = models.CharField(max_length=16, choices=Gender, default='MALE')
Diseases = models.CharField(max_length=16, choices=Diseases, default='MALARIA')
vote = models.IntegerField(default=0)
def __str__(self):
return self.Gender
def __str__(self):
return self.Diseases
result.html
{% extends 'polls/base.html' %}
{% block main_content %}
<h1></h1>
<ul>
{% for choice in Gender %}
<li> {{choice.Gender}} - {{choice.Diseases}} - {{ choice.Number}}</li>
{% endfor %}
</ul>
Vote Again?\\
{% endblock %}
Your template is at "polls/result.html" but you told the view it was "poll/result.html".
(Note, you really shouldn't give your URLs paths ending in "html"; it's not necessary, and it's confusing you. URLs and template locations have nothing to do with each other.)
Related
I am using class based views to create a post. I have used get_absolute_url to go to the post page after clicking on post but it is giving an error of no reverse match.
this is my modelspy
from django.db import models
from django.conf import settings
from django.urls import reverse
# Create your models here.
class BlogPost(models.Model):
title = models.CharField(max_length = 50 , null=False,blank=False)
body = models.TextField(max_length = 5000 , null=False,blank=False)
date_published = models.DateTimeField(auto_now_add=True)
date_update = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('article-detail', args=(str(self.id)))
this is my urls.py:
urlpatterns = [
path('',views.home,name="home"),
path('home2/',HomeView.as_view(),name = "home2"),
path('article/<int:pk>',ArticleDetailView.as_view(),name = "article-detail"),
path('add_post/',AddPostView.as_view(),name="add_post"),
]
this is home2.html:
<ul>
{%for post in object_list %}
<li>{{post.title}}-{{post.author}}<br/>
{{post.body}}</li>
{%endfor%}
</ul>
this is views.py:
from django.shortcuts import render
from .models import *
from .forms import *
from django.views.generic import ListView,CreateView
from django.views.generic.detail import DetailView
# Create your views here.
def home(request):
return render(request,'post/home.html')
class HomeView(ListView):
model = BlogPost
template_name = "post/home2.html"
class ArticleDetailView(DetailView):
model = BlogPost
template_name = "post/article_details.html"
context_object_name = 'post'
class AddPostView(CreateView):
model = BlogPost
template_name = "post/add_post.html"
fields = '__all__'
I would suggest doing something like. I provide 2 methods.
1st method:
By using get_absolute_url
from django.urls import reverse
def get_absolute_url(self):
return reverse('post:article-detail', args=(self.id)) #post is the app_name
urls.py
url(r'^article/(?P<pk>\d+)/$', ArticleDetailView.as_view(), name='article-detail'),
home2.html
<ul>
{%for post in object_list %}
<li>
{{post.title}}-{{post.author}}<br/>{{post.body}}
</li>
{%endfor%}
</ul>
2nd Method:
By using template tag.Here get absolute url with help of template tag.
home2.html
{% load templatehelpers %}
<ul>
{%for post in object_list %}
<li>
{{post.title}}-{{post.author}}<br/>
{{post.body}}
</li>
{% endfor %}
</ul>
Here we use a new simple tag namely abs_url (absolute url) in templatehelpers.py (Template tag). And app_name is the name of the app.
templatehelpers.py
from django import template
from django.urls import reverse
register = template.Library()
#register.simple_tag
def abs_url(value, request, **kwargs):
return reverse(value,kwargs=kwargs)
If you change this
def get_absolute_url(self):
return reverse('article-detail', args=(str(self.id)))
to this
def get_absolute_url(self):
return reverse('home')
You will not get the error, but you will not either be redirected to the post you just posted.
So if your goal is to just get rid of this error, but don't care about where you get redirected afterwards, then this is the solution for you.
I want to use the {{ post.title }} and {{ for post in object_list }}
into my home template to show the latest 4 posts, I tried to import from blog.models import Post, but it doesn't work. I guess I'm putting it in the wrong place.
blog.models
from django.db import models
from ckeditor.fields import RichTextField
class Post(models.Model):
title = models.CharField(max_length = 140)
image = models.ImageField(upload_to="media", blank=True)
body = RichTextField(config_name='default')
date = models.DateField()
def __str__(self):
return self.title
home.urls
from django.urls import path
from . import views
urlpatterns = [
path('', views.HomePageView.as_view(), name='home'),
]
home.views
from django.views.generic import TemplateView
from allauth.account.forms import LoginForm
class HomePageView(TemplateView):
template_name = 'home/index.html'
mysite tree look like this
mysite
home
admin
app
models
tests
urls
views
blog
admin
app
models
tests
urls
views
You can override get_context_data and add the latest blog posts to the template context.
from blog.models import Post
class HomePageView(TemplateView):
template_name = 'home/index.html'
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
context['object_list'] = Post.objects.order_by('-date')[:4]
return context
I am a beginner to Django.
I want to create a form that allow user to store their data to the database, but I face to an issue.
If I add data through Django admin, the data will shown correctly. But if I add data through my form. Data will store into database successfully but they don't shown in my Django admin.
Note: The Django version I used is 1.11.2
The is my Django admin page. There are 8 data in the database but just show the one I added by the Django admin.
views.py
from django.shortcuts import render
from django.views.generic import CreateView
from .forms import ApplyFormCreateForm
from .models import ApplyForm
class ApplyFormCreateView(CreateView):
form_class = ApplyFormCreateForm
template_name = 'form.html'
success_url = "/"
models.py
from django.db import models
from course.models import Semester
DEFAULT_SEMESTER_ID = 1
class ApplyForm(models.Model):
name = models.CharField(max_length=15)
school = models.CharField(max_length=20)
department = models.CharField(max_length=20)
email = models.EmailField(max_length=100)
is_beginner = models.BooleanField(default=False)
introduction = models.TextField(max_length=2000)
motivation = models.TextField(max_length=2000)
comments = models.TextField(max_length=2000, blank=True)
semester = models.ForeignKey(Semester, default=DEFAULT_SEMESTER_ID)
created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.school + self.department + self.name
def __str__(self):
return self.school + self.department + self.name
form.html
{% extends "base.html" %}
{% block content %}
<form method='POST'> {% csrf_token %}
{{form.as_p}}
<button type='submit'>Save</button>
</form>
{% endblock content %}
form.py
from django import forms
from .models import ApplyForm
class ApplyFormCreateForm(forms.ModelForm):
class Meta:
model = ApplyForm
fields = [
'name',
'school',
'department',
'email',
'is_beginner',
'introduction',
'motivation',
'comments',
]
url.py
from django.conf.urls import url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from myweb.views import HomeView
from course.views import CourseListView
from applyform.views import ApplyFormCreateView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', HomeView.as_view(), name='home'),
url(r'^course/$', CourseListView.as_view(), name='course'),
url(r'^apply/$', ApplyFormCreateView.as_view(), name='applyform'),
]
I need to validate a condition in my Experiment class that depends on more than one field. I specified a 'clean' method in my ExperimentForm, but the validation method is never raised. The model's validation errors are perfectly displayed.
This is how the forms.py looks like:
from django import forms
from django.utils.translation import ugettext, ugettext_lazy as _
class ExperimentForm(forms.Form):
name = forms.CharField(max_length=254)
student_n = forms.IntegerField()
expert_n = forms.IntegerField()
student_cmd_n = forms.IntegerField()
expert_cmd_n = forms.IntegerField()
is_active = forms.BooleanField()
error_messages = {
'insufficient_assignments': _("The total number of commands to be evaluated must be"
"Greater than 28. Right now it's %(command_number)"),
}
def clean(self):
cleaned_data = super(ExperimentForm, self).clean()
s_n = cleaned_data.get("student_n")
e_n = cleaned_data.get("expert_n")
s_cmd_n = cleaned_data.get("student_cmd_n")
e_cmd_n = cleaned_data.get("expert_cmd_n")
command_number = s_n*s_cmd_n + e_n*e_cmd_n
if command_number < 28:
raise forms.ValidationError(
self.error_messages['insufficient_assignments'],
code='insufficient_assignments',
params={'command_number': command_number},
)
return self.cleaned_data
This is my views.py
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader
from django.core.urlresolvers import reverse_lazy
from vacs.forms import ExperimentForm
from django.views.generic import TemplateView,ListView
from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
from django.views.generic.detail import DetailView
from vacs.models import Experiment
class ExperimentView(FormView):
template_name = 'vacs/experiment.html'
form_class = ExperimentForm
success_url = '/vacs/experiments/'
def form_valid(self, form):
return super(ExperimentView, self).form_valid(form)
class ExperimentDetailView(DetailView):
model = Experiment
class ExperimentListView(ListView):
model = Experiment
class ExperimentCreateView(CreateView):
model = Experiment
success_url = reverse_lazy('experiment_list')
fields = ['name', 'student_n', 'expert_n', 'student_cmd_n', 'expert_cmd_n']
class ExperimentUpdateView(UpdateView):
model = Experiment
success_url = reverse_lazy('experiment_list')
fields = ['is_active' ]
class ExperimentDeleteView(DeleteView):
model = Experiment
success_url = reverse_lazy('experiment_list')
The models.py is defined in the following way:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
from django.utils.encoding import python_2_unicode_compatible
from django.contrib.auth.models import User
from django.db import models
from jsonfield import JSONField
import collections
class Experiment(models.Model):
name = models.CharField(max_length=200)
student_n = models.IntegerField(default=0,
validators=[MinValueValidator(0)])
expert_n = models.IntegerField(default=0,
validators=[MinValueValidator(0)])
student_cmd_n = models.IntegerField(default=2,
validators=[MinValueValidator(2)])
expert_cmd_n = models.IntegerField(default=1,
validators=[MinValueValidator(1)])
is_active = models.BooleanField(default=True)
replications = JSONField(load_kwargs={'object_pairs_hook': collections.OrderedDict},
blank=True)
Finally, the template experiment_form.html:
{% extends "vacs/base.html" %}
{% load widget_tweaks %}
{% block content %}
{% if form.errors %}
<div class="alert alert-danger" role="alert">
Form error!
</div>
{% endif %}
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
Thank you!
You need to override the save method for the model.
So to run clean_fields() and clean() Add the following method to your model
def save(self, *args, **kwargs):
self.full_clean()
return super().save(*args, **kwargs)
Three types of cleaning methods are run during form processing. These are normally executed when you call the is_valid() method on a
form.
Django documentation
I was writing a model online shop django app, wanted to incorporate slug in it. Having trouble in opening a page.
This is my model:
from __future__ import unicode_literals
from django.db import models
from django.db.models.signals import pre_save
from django.utils .text import slugify
class Customer(models.Model):
customer_name = models.CharField(max_length=200)
slug = models.SlugField(unique = True)
def __str__(self):
return self.customer_name
def get_absolute_url(self):
return reverse("OnlineShop:order", kwargs={"slug": self.slug})
def pre_save_customer_receiver(sender, instance, *args, **kwargs):
slug = slugify(instance.customer_name)
exists = Customer.objects.filter(slug = slug).exists()
if exists:
slug = "%s-%s" % (slug,instance.id)
instance.slug=slug
pre_save.connect(pre_save_customer_receiver, sender = Customer)
This is my view:
def customer(request):
customer_list = Customer.objects.all()
template_path = 'OnlineShop/customer.html'
context={
'customer_list':customer_list,
}
return render(request,template_path,context)
def order(request,slug):
Customer = Customer.objects.filter(slug=slug)
''' some code from here '''
And my template customer.html:
<h1>List of Customers:</h1>
<ul>
{% for customer in customer_list %}
<li><a href='{% url 'order' customer.slug %}'>{{ customer.customer_name }}<br></li>
{% endfor %}
</ul>
This is my urls.py
from django.conf.urls import url
from . import views
urlpatterns=[
url(r'^$',views.customer, name='customer'),
url(r'^customer/(?P<slug>[\w-]+)$',views.order, name='order'),
]
Is the problem in the template? What is wrong?
I hope you've defined your urls.py like below,
from django.conf.urls import url, include
from . import views
onlineshop_patterns = [
url(r'^$', views.customer, name='customer'),
url(r'^customer/(?P<slug>[\w-]+)$', views.order, name='order'),
]
urlpatterns = [
# ...
url(r'^OnlineShop/', include(onlineshop_patterns)),
# ...
]
Read Reverse resolution of URLs and Regex for SlugField.