TemplateDoesNotExist at /app/detail/3/ - python

I got an error,
TemplateDoesNotExist at /app/detail/3/ app/post_detail.html.
I wrote the following:
def top(request):
content = POST.objects.order_by('-created_at')[:5]
page = _get_page(blog_content, request.GET.get('page'))
return render(request, 'top.html',{'content':content,"page":page})
class DetailView(generic.DetailView):
model = POST
def detail(request, pk):
content = POST.objects.get(id=pk)
return render(request, 'detail.html',{'content': content})
in top.html
<div>
{% for content in page %}
<h2>{{ content.title }}</h2>
<p>SHOW DETAIL</p>
{% endfor %}
</div>
in detail.html
<h2>{{ content.title }}</h2>
<p>{{ content.text }}</p>
When I access top.html, ordinary web site is shown, so it is ok. But when I put SHOW DETAIL links the error happens.
I did not write post_detail.html anywhere in my code, so I really cannot understand why post_detail.html causes the mistake.
As a test,I made post_detail.html in same directory with top.html and detail.html, but the same error happens. I want to make a system when I put SHOW DETAIL links, the content's detail is shown.
How should I fix this? What is wrong in my code?
After reading answer,I rewrote DetailView of views.py
class DetailView(generic.DetailView):
model = POST
template_name = 'detail.html'
but when I put SHOW DETAIL links, nothing is shown there.I wrote in detail.html
<h2>{{ post.title }}</h2>
<p>{{ post.text }}</p>
Am I wrong to write the way of detail.html or views.py?How can I show detail's content?

You are using a generic detail view for the POST detail. Generic views do not expect or use a detail() method, and either look for a template as specified in the template_name class attribute or the default which is modelname_detail.html.
You should either make your view a standard function view - like the "top" one - by moving the detail method out of that class; or, remove the method altogether (because it just does what the generic view does already) and either rename your template to post_detail.html or set template_name = 'detail.html'.

Related

'WSGIRequest' object has no attribute 'htmx'

Hi just looking for some help at solving this error in Django whilst trying to call a view that to accept a htmx request. The final result is to display a popup Modal of images from a Gallery when a thumbnail is clicked.
HTMX installed via script in head.
View
if request.htmx:
slug = request.GET.get('slug')
context = {'pictures': Media.objects.filter(slug=slug)}
return render(request, 'main/gallery-detail.html', context=context)
context = {'objects_list': Albums.objects.all()}
return render(request, 'main/gallery.html', context=context)
Relevant html with the button to open gallery of images.
<a class="btn btn-primary" hx-post="{{ request.path }}?slug={{ img.slug }}" hx-target="#modal">
{{ img.slug }}</a>
{% endfor %}
<div id="modal">{% include "main/gallery-detail.html" %}</div>
This error mostly occurs if you haven't included django-htmx in the settings.py.
Try making the below changes and see if it works :
Add "django_htmx.middleware.HtmxMiddleware" to the MIDDLEWARE.
Add "django_htmx" to the INSTALLED_APPS.

Django - No Reverse Match Error - URL only works with static values

I'm working on a Django site that displays a list of projects. You go to a page, you see a project, you click it, and you can then see project details and have the option to edit the page.
For each individual project, I use a template called project.html. Then on that page, I have a link to edit_project.html
Edit Project
Whenever I try to load the project page to view, I get this error:
Reverse for 'edit_project' with arguments '('',)' not found. 1
pattern(s) tried: ['edit_project/(?P\d+)/$']
I checked the urls, and they seemed fine. So, I tried hard-coding a project id that I knew was in the database. For example, I called:
Edit Project
instead of calling that same thing with "project.id". When I did that, the error went away.
Why does this work with a hard-coded value instead of a project.id variable?
I also tried deleting the database and all the migrations in case something strange was happening there. I got the same issue though.
Here is the code I used to set everything up in case it is helpful.
project.html
{% extends "profile/base.html" %}
{% block content %}
<p>
Edit Project
</p>
<p>Status: {{ status }}</p>
{% endblock content %}
edit_project.html
{% block content %}
<p>{{ project }}</p>
<p>Edit project:</p>
<form action="{% url 'profile:edit_project' project.id %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Save Changes</button>
</form>
{% endblock content %}
views.py
#login_required
def edit_project(request, project_id):
"""Edit an existing project"""
project = Project.objects.get(id=project_id)
#Make sure the project belongs to the owner
if project.owner != request.user:
return Http404
if request.method != 'POST':
#Initial request; pre-fill form with the current entry
form = ProjectForm(instance=project)
else:
#POST data submitted; process data
form = ProjectForm(instance=project, data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('profile:project',args=[project.id]))
context = {'project':project, 'form':form}
return render(render, 'profile/edit_project.html', context)
(project) forms.py
class DateInput(forms.DateTimeInput):
input_type = 'date'
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ['name','description','status', 'project_type', 'start_date','end_date', 'due_date']
labels = {'name':'Name', 'description':'Description:', 'status':'Status', 'project_type':'Project Type',
'start_date':'Start Date', 'end_date':'End Date', 'due_date': 'Due Date',}
widgets ={'description':forms.Textarea(attrs={'cols':80}),'start_date':DateInput(),
'end_date':DateInput(),'due_date':DateInput()}
urls.py
urlpatterns = [
#Home page
url('^$', views.index, name='index'),
#Show all projects
url('projects/$', views.projects, name='projects'),
#Details for single project
url('^projects/(?P<project_id>\d+)/$', views.project, name='project'),
#Page for editing a single project
url('^edit_project/(?P<project_id>\d+)/$', views.edit_project, name='edit_project'),
]

Ideal page is not shown

Ideal page is not shown.
I wrote in views.py
def top(request):
content = POST.objects.order_by('-created_at')[:5]
return render(request, 'top.html',{'content':content})
def detail(request,pk):
content = POST.objects.order_by('-created_at')[:5]
return render(request, 'detail.html',{'content':content})
in top.html
<div>
{% for item in content %}
<h2>{{ item.title }}</h2>
<p>SHOW DETAIL</p>
{% endfor %}
</div>
in detail.html
<div>
<h2>{{ content.title }}</h2>
<p>{{ content.text }}</p>
</div>
in urls.py
urlpatterns = [
path('top/', views.top, name='top'),
path('detail/<int:pk>/',views.detail , name='detail'),
]
When I access top method, top.html is shown.And when I click SHOW DETAIL url link, detail.html is shown.But in this detail.html,always content is same.I wanna make a system when I click this link, detail's content is changed each content.pk.But now my system is not my ideal one.Why does my system always return same content in detail.html?How should I fix this?
Well, you're not pulling the object being requested - it's just the same query to pull the list. You need to use Model.objects.get() in order to retrieve the detail for the object.
def detail(request,pk):
# Get the object with the matching pk
content = POST.objects.get(id=pk)
return render(request, 'detail.html',{'content':content})
You should also look into Class Based Views (CBVs) as what you're doing could be simplified with a DetailView and ListView.
In
def detail(request,pk):
content = POST.objects.order_by('-created_at')[:5]
return render(request, 'detail.html',{'content':content})
You're not doing anything with the primary key (pk). You go to the database and fetch the 5 most recent posts. Don't you want it to be:
def detail(request,pk):
content = POST.objects.get(pk=pk)
return render(request, 'detail.html',{'content':content})
?
Since you're doing this for views, I recommend you also take a look to get_object_or_404
I think you've used the content variable instead of item in top.html, it's always taking pk of first element from list. Check below code.
<div>
{% for item in content %}
<h2>{{ item.title }}</h2>
<p>SHOW DETAIL</p>
{% endfor %}
</div>

django can't load the model's information to template

I'm using Django with MySQL. I have a Post model. If I execute Post.object.all() in python shell, it shows all the Post objects.
However, when I add
posts = Post.objects.all()
return render(request, 'index.html', {'posts': posts})
in views.py
and
{% for post in posts %}
{{ post.title }}
{% endfor %}
in index.html
I simply can't see the post names on my index page. What's wrong with my codes ? How can I know if I have passed posts to the template successfully?

Loading page in Django based on its ID

I've been working with Django in order to make my portfolio and I've managed to make a simple page manager. The problem is, it does not work how I want it to work:
I create the page.
It loads the content I gave it.
With jQuery, I load only that content (as formatted HTML).
It shows itself without reloading or moving to another page.
The problem is with the last two steps, I can't get the view and template to only load one.
Views.py:
def paginas(request, title):
get_page = Page.objects.all() # I can't think of a way to make a proper filter
return render_to_response('template.html', {'get_page': get_page}, context_instance=RequestContext(request), mimetype="text/html")
Template.html:
{% if get_page %}
{% for page in get_page %}
{{ page.content|safe }}
<p>Full path is {{ request.get_full_path }} and page id is {{ page.id }}</p>
{% endfor %}
{% else %}
<p>Nothing.</p>
{% endif %}
I know I should filter it, but I don't know how.
I appreciate your help.
tbh, the django tutorial explains urls, parameters and forms very clear, but here's the idea:
url(r'^/someapp/(?P<page_id>\d+)/$', paginas),
def paginas(request, **kwargs):
id = kwargs.pop('page_id')
page = get_object_or_404(Page, id=id)
# etcetera
class Page(models.Model):
# regular stuff
def get_absolute_url(self):
return "/someapp/%d/" % self.id
In paginas you are obviously getting all Pages.
To get one page you can use the get function
def paginas(request, title):
try:
your_page = Page.objects.get(title=title)
except Page.DoesNotExist:
# error no page for that title
# could use built in get_object_or_404 as ArgsKwargs suggested
It's also important to consider using a slug to make sure encoding is correct. The page id would be even better to use

Categories