from django.views import generic
from .models import Inspectionfile
from .models import posts
class IndexView(generic.ListView):
template_name = "posts/index.html"
def get_queryset(self):
return Inspectionfile.objects.all()
class DetailView(generic.DetailView):
model = Inspectionfile
template_name = "posts/detail.html "
#index template
<ul>
{% for o in object_list %}
<li>{{o.document_title}} </li>
{% endfor %}
</ul>
#detail template
<h1>{{ o.document_title }}</h1>
My Index template works but the detail template does not seem to take the value so just appears blank . So is the 'o' not being passed to detail ?? I have not been able to solve this. BTW document_title is one of the field of my inspectionfile model. I checked my url regex and it seems to work fine.
o is an object which only exists within the for loop in your list view template. It isn't passed anywhere.
The detail view has its own context; there the object that is identifued by the url argument is called just object.
Related
I am creating a Q&A website for practice, I created the answer and the question model and linked them together, however I can not access the template that I set for the deletion of the answer model, I created a DeleteView to delete the question. Here is the code:
views.py:
class Politics_post_details(DeleteView):
model = PoliticsPost
context_object_name = 'politicsposts'
pk_url_kwarg = 'qid'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# now you can get any additional information you want from other models
question = get_object_or_404(PoliticsPost, pk=self.kwargs.get('qid'))
context['answers'] = Answer.objects.filter(post=question).order_by('-date_posted')
return context
class AnswerDelete(UserPassesTestMixin,DetailView):
model = Answer
success_url = reverse_lazy('Lisk home')
pk_url_kwarg = 'aid'
def test_func(self):
answer = self.get_object()
if self.request.user ==answer.author:
return True
return False
urls.py(not root):
path('politicspost/<int:qid>/createanswer/',views.CreateAnswer.as_view(template_name='lisk_templates/createanswer.html'),name = 'Answer'),
path('politicspost/<int:qid>/answer/<int:aid>/delete/',views.AnswerDelete.as_view(template_name = 'lisk_templates/answer_delete.html'),name='Answer_Delete'),
path('politicspost/<int:qid>/',views.Politics_post_details.as_view(template_name='lisk_templates/politics_post_details.html'),
I created the template but whenever I try to access it, it gives me an error as follows:
NoReverseMatch at /politicspost/29/
Reverse for 'Answer_Delete' with arguments '(36,)' not found. 1 pattern(s) tried: ['politicspost/(?P<qid>[0-9]+)/answer/(?P<aid>[0-9]+)/delete/$']
Thanks in advance.
answer_delete.html:
{%extends "lisk_templates/base.html"%}
{% block title %}
Page title
{% endblock title %}
{% block body%}
<div class="feed" style="background-color:lightred;"><form method="POST">
{% csrf_token %}
<h3>Are you sure that you want to delete this answer: <br>
{{ object.content }}</h3>
<button id="signin" type="submit">Yes</button> No
</form>
</div>
{% endblock body %}
You have a number of issues. The biggest one is that you have switched DeleteView and DetailView (your DeleteView is a DetailView and vice versa).
And then you should either rename your template to answer_confirm_delete or add the template_name_suffix to your DeleteView. See the documentation for further details:
https://docs.djangoproject.com/en/3.0/ref/class-based-views/generic-editing/#django.views.generic.edit.DeleteView
If you use Django's DeleteView, you don't need to specify a url in the template, it will do all the work for you. Just make sure you specify the url correctly in your urls.py. Fix these issues and see if it works then.
May Be This Might Work For You, Because You Never Used The Import Of DeleteView
from django.views.generic import DeleteView
"""This Is From My Blog App, That I Used For My Blog App, Hope This Will Help"""
class PostDeleteView(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('post_list')
Happy Coding, let me know if there are any issues with this I'am Up for you!
I'm trying to get validation running on a django form used to retrieve a list of objects in a ListView View. Despite having read django docs and many other questions here, I can't find out what's wrong in this simple test code:
form.html
<form action="list.html" method="get">
{{ form }}
<input type="submit" value="Submit">
</form>
list.html
<ul>
{% for area in object_list %}
<li>{{ area.name }}</li>
{% endfor %}
</ul>
forms.py
from django import forms
class SearchArea(forms.Form):
area = forms.CharField(label='Area code', max_length=6)
def clean_area(self):
area = self.cleaned_data['area'].upper()
if '2' in area:
raise forms.ValidationError("Error!")
return area
views.py
class HomePageView(FormView):
template_name = 'form.html'
form_class = SearchArea
class AreaListView(ListView):
template_name = 'list.html'
model = AreaCentral
def get_queryset(self):
q = self.request.GET.get('area')
return AreaCentral.objects.filter(area__istartswith=q)
When I try to submit something like "2e" I would expect a validation error, instead the form is submitted. Moreover I can see in the GET parameters that 'area' is not even converted to uppercase ('2E' instead of '2e').
The default a FormView will only process the form on POST; the GET is for initially displaying the empty form. So you need to use method="post" in your template form element.
Your action attribute is also suspect; it needs to point to the URL of the form view. If that actually is the URL, note it's not usual to use extensions like ".html" in Django URLs, and I would recommend not doing so.
I am a newbie to django and need some help. I have a created a vaguely functioning website. I have a model which looks as follows;
from django.db import models
class InductiveSensors(models.Model):
Part_No = models.CharField(max_length=250)
Manufacturer = models.CharField(max_length=250)
Sn = models.CharField(max_length=250)
AssuredSn = models.CharField(max_length=250)
def __str__(self):
return InductiveSensors.Manufacturer
There are a couple of pages. one which gives me a list of all items in the database
{% extends "ESensFind/header.html" %}
{% block content %}
{% for InductiveSensors in object_list %}
<h5>{{ InductiveSensors.Manufacturer}}<a
href="/Inductive_Search/{{InductiveSensors.id}}">
{{InductiveSensors.Part_No}}</a></h5>
{% endfor %}
{% endblock %}
When the {{InductiveSensors.Part_No}} link is clicked it opens up another page. On which I would like to display this database entry in a table with the information of
Part_No = models.CharField(max_length=250)
Manufacturer = models.CharField(max_length=250)
Sn = models.CharField(max_length=250)
AssuredSn = models.CharField(max_length=250)
my urls look like:
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from Inductive_Search.models import InductiveSensors
urlpatterns = [
url(r'^$',ListView.as_view(queryset=InductiveSensors.objects.all().order_by
("Manufacturer") #THIS PAGE IS THE LIST OF ALL DATABASE ENTRIES#
[:25],template_name="Inductive_Search/Inductive_Search.html")),
url(r'^(?P<pk>\d+)$', ListView.as_view(model= InductiveSensors,
template_name = 'Inductive_Search/SensorInfo.html')) #THIS OPENS UP A NEW
INDEX PAGE AFTER A PARTICULAR DATABASE ENTRY LINK IS CLICKED#
is the 2nd url code correct to work in conjunction with "SensorInfo.html"? In "SensorInfo.html" i have this code, which I would think should display even just the manufacturer information in a header but it displays nothing.
{% extends "ESensFind/header.html" %}
{% block content %}
<h5>{{ InductiveSensors.Manufacturer}}</h5>
{% endblock %}
Essentially what I am trying to do is get SensorInfo.html to display the values from my model, relating to that particular index in a table on my webpage. Any help would be appreciated. Thanks
The "right" solution is to write detail view (by deriving from DetailView), when in the template you can access the underlying object using get_object() or .object.
If you want to implement it quick and dirty, you have to access the pk argument and using it get the model instance, and pass it as part of the context data.
I suggest you dig into documentation, the django tutorial is good place to start (https://docs.djangoproject.com/en/2.0/intro/tutorial01/#writing-your-first-django-app-part-1) or read on class based views here https://docs.djangoproject.com/en/2.0/topics/class-based-views/generic-display/
So would a solution be something like the following to urls.py?
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from Inductive_Search.models import InductiveSensors
urlpatterns = [
url(r'^$',
ListView.as_view(queryset=InductiveSensors.objects.all().order_by
("Manufacturer")
[:25],template_name="Inductive_Search/Inductive_Search.html")),
url(r'^(?P<pk>\d+)$', DetailView.as_view(model= InductiveSensors,
template_name = 'Inductive_Search/SensorInfo.html'))
]
and in the template
{% extends "ESensFind/header.html" %}
{% block content %}
<h5>{{ get_object() }}</h5>
{% endblock %}
I have started learning django, I'm not sure how generic view works. I read django documentation several times, I can't gain clear understanding of how generic view works. Very strange but it works well. It retrieves data from the database and renders data on the browser.
Here is snippet code of polls/urls.py.
url(r'^$', views.IndexView.as_view(), name = 'index')
It will go to the IndexView class in views.py.
Here is snippet code of polls/views.py.
from django.views import generic
from .models import Question, Choice
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
return Question.objects.order_by('-pub_date')[:5]
When I change template_name as something, the exception has occurred as follows.
TemplateDoesNotExist: polls/question_list.html
What does question_list.html mean?
Where does it come from?
And here is index.html.
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li>
{{ question.question_text }}
</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
As you can see, index.html file use latest_question_list as a parameter but I'm not sure how can the latest_question_list be used.
In views.py file, what does context_object_name = 'latest_question_list' mean?
Where does the 'latest_question_list' come from and how can index.html use latest_question_list?
Do I use context_object_name in views.py?
What's the role of the get_queryset() function?
What does question_list.html mean?
It means that there is a file inside polls dir like index.html
if you want to have a file with a diff name you have to change the name of template_name='polls/name_of_file_inside_polls'
Do I use context_object_name in views.py?
The context is the place where you put some vars to use it in your templates, that's why you can use latest_question_list
What's the role of the get_queryset() function?
It creates the query that is passed to the template.
I understand what they mean.
By default, the DetailView generic view uses a template called /_detail.html. In my case, it would use the template "polls/question_detail.html". The template_name attribute is used to tell Django to use a specific template name instead of the autogenerated default template name. I also specify the template_name for the results list view – this ensures that the results view and the detail view have a different appearance when rendered, even though they’re both a DetailView behind the scenes.
For DetailView the question variable is provided automatically – since we’re using a Django model (Question), Django is able to determine an appropriate name for the context variable. However, for ListView, the automatically generated context variable is question_list. To override this we provide the context_object_name attribute, specifying that we want to use latest_question_list instead.
So i'm trying to filter my model in this way in views.py:
news_list = list(models.Entry.objects.filter(category='news'))
and the problem is that the list cant be accessable from the django templates.
this is the way I'm trying to access it in home.html:
{% for news in news_list %}
{{ news.title }}
{% endfor %}
and this:
{{ news_list.0.title }}
I'm sure the way that I created the list is right beauce when I loop through the list in the views.py it show up in the terminal.
I'm using python3.3 and django 1.8.3
views.py :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.views import generic
from . import models
from blog.models import Entry
class BlogIndex(generic.ListView):
queryset = models.Entry.objects.published()
template_name = "home.html"
paginate_by = 3
news_list = Entry.objects.filter(category='news')
i = 0
for x in news_list:
i = i+1
print(x.title,i)
You are trying to access news_list in the template when it is infact not present in the template.
You need to pass news_list in the context data. Override the get_context_data() and pass this variable.
class BlogIndex(generic.ListView):
queryset = models.Entry.objects.published()
template_name = "home.html"
paginate_by = 3
def get_context_data(self, **kwargs):
context = super(BlogIndex, self).get_context_data(**kwargs)
context['news_list'] = Entry.objects.filter(category='news') # pass 'news_list' in the context
return context
Then in your template, you can use the normal for loop.
{% for news in news_list %}
{{ news.title }}
{% endfor %}
Note: You don't need to convert the QuerySet to a list as it is already an iterable.
The queryset result can be used to iterate in django template. So there is no need to convert query set object into list. List is not iterable in django template though python does. You can use django-mptt is a premade solution, which should fit your problem quite good.
That's because in django you don't access lists, but querysets. Try:
context['news_list'] = Entry.objects.filter(category='news')