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
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.
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.
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>
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?
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