I'm receiving this error:
NoReverseMatch at /comments_page/1/post_comment/
Reverse for 'post_comment' with arguments '('',)' not found. 1 pattern(s) tried: ['comments_page/(?P[0-9]+)/post_comment/$']
My views.py
def post_comment(request, product_id):
host_product = Product.objects.get(pk=product_id)
comment = Comment()
comment.product = host_product
comment.author = request.POST["author"]
comment.comment_text = request.POST["comment"]
comment.save()
return render(request, 'comments_page/detail.html', {"host_product": host_product})
My comments_page\urls.py
from django.conf.urls import url
from . import views
app_name = "comments_page"
urlpatterns = [
# /comments_page/
url(r'^$', views.index, name="index"),
# /comments_page/1/
url(r'^(?P<product_id>[0-9]+)/$', views.detail, name="detail"),
# /comments_page/1/post_comment/
url(r'^(?P<product_id>[0-9]+)/post_comment/$', views.post_comment, name='post_comment'),]
My detail.html
<form action="{% url 'comments_page:post_comment' product.id %}" method="post">
{% csrf_token %}
Name: <input type="text" id="author" name="author">
Comment:
<textarea id="comment" name="comment"></textarea><br>
<input type="submit" value="Post Comment">
I think I've identified the problem as being in the product.id here
{% url 'comments_page:post_comment' product.id %}
in the html page. I've tried formatting this a couple of different ways, but I haven't had any luck. Do note, the comment is going through and the form and it works as far as updating the database and loading the entry on the page goes, but the page is not being redirected. I have to reload it manually. Any help would be appreciated.
The error message shows that the argument you pass to the {% url %} tag does not exist and resolves to an empty string. Your view indeed does not pass in a product variable, only a host_product variable. You need to change the tag accordingly:
{% url 'comments_page:post_comment' host_product.id %}
For those who may wonder, the fix is to change the return function in views.py to this
return render(request, 'comments_page/detail.html', {"product": host_product})
I do not understand why this works, but it does. Any suggestions as to how to clean up my post_comment function would be appreciated. I feel it's overly convoluted by using host_product
Related
I am working on to do app, and I cannot solve this problem.
The problem is linking the tasks with ID or PK...
i am getting this error:
NoReverseMatch at /
Reverse for 'update_task' with arguments '(1,)' not found. 1 pattern(s) tried: ['update_task/
and it is pointing that error is here (in template):
Update
views.py
def updateTask(request, pk):
task = Task.objects.get(id=pk)
form =TaskForm(instance=task)
context = {'form': form}
return render(request, 'tasks/update_task.html',context)
template
<h3>To Do</h3>
<form action='/' method="POST">
{% csrf_token %}
{{form.title}}
<input type="submit" name="Create Task">
</form>
{% for task in tasks %}
<div class="">
Update
<p>{{task}}</p>
</div>
{% endfor %}
URLS.PY
from django.urls import path
from tasks import views
urlpatterns = [
path('', views.index, name='list'),
path('update_task/<str:pk/', views.updateTask, name='update_task'),
]
this will help you
path('update_task/<str:pk>/',views.updateTask, name='update_task'),
So I'm building this learning log app where users can create multiple topics. I'm trying to create a single page where users can edit/save changes/delete their topic names. My logic in the edit_topic view function is to display the original topics in forms with save and delete button, code below or feel free to check GitHub Repo:
views.py
def edit_topics(request, topic_pk=None):
'''edit existing topics mainly the names'''
# modify the model data according to the request method and name
if request.method == 'POST' and topic_pk != None:
if 'save' in request.POST:
topic_to_change = get_object_or_404(Topic, pk=topic_pk)
form = TopicForm(instance=topic_to_change, data=request.POST)
if form.is_valid():
form.save()
elif 'delete' in request.POST:
topic_to_delete = get_object_or_404(Topic, pk=topic_pk)
topic_to_delete.delete()
return redirect('learning_logs:edit_topics')
# get the original/modified data passing to render
topics = Topic.objects.all()
topic_lst = []
for topic in topics:
form = TopicForm(instance=topic)
topic_lst.append(form)
context = {'topics': topics, 'topic_lst': topic_lst}
return render(request, 'learning_logs/edit_topics.html', context)
edit_topics.html
{% extends 'learning_logs/base.html' %}
{% block content %}
<section class="container">
<h3>Topics you have created</h3>
<ul class="">
{% for form in topic_lst %}
<li class="mb-5">
<form class="d-flex align-items-center"
action="{% url 'learning_logs:edit_topics' form.instance.pk %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-primary" name="submit">save</button>
<button class="btn btn-danger" name="delete">delete</button>
</form>
</li>
{% endfor %}
</ul>
<a class="btn btn-info" href="{% url 'learning_logs:topics' %}">Done</a>
</section>
{% endblock content %}
url.py
from django.urls import path
from . import views
app_name="learning_logs"
urlpatterns = [
path('', views.index, name='index'),
path('topics/', views.topics, name='topics'),
path('topics/edit/', views.edit_topics, name='edit_topics'),
path('new_topic/', views.new_topic, name='new_topic'),
path('topic_<int:topic_pk>/', views.topic, name='topic'),
path('topic_<int:topic_pk>/new_entry/', views.new_entry, name='new_entry'),
path('topic_<int:topic_pk>/entry_<int:entry_pk>/', views.entry, name='entry'),
path('topic_<int:topic_pk>/entry_<int:entry_pk>/edit_entry/', views.edit_entry, name='edit_entry'),
]
However, I think there might be some logic error, it keeps raising NoReverseMatch(msg) django.urls.exceptions.NoReverseMatch: Reverse for 'edit_topics' with arguments '(1,)' not found. 1 pattern(s) tried: ['topics/edit$']
If I delete form.instance.pk in edit_topics.html file, no error is raised. But consequently, the if logic in the view function wouldn't take action... I'm fairly new to programming, I'm sure there're some logic errors as well --
I'm struggling with the topic_pk optional argument in the view function because I'm not sure how to pass it in correctly.
Ideally, I hope the users can edit, save or delete the topics on this page one by one, and after they click save or delete the page will redirect back to this view and render the updated topic text. At the end, when they are done, they can click the Done button at the end...
Please help! Thanks!!
Feel free to check GitHub Repo for Learning_Log app
Update your url like this:
path('topics/edit/', views.edit_topics, name='edit_topics'),
path('topics/edit/<int:topic_pk>/', views.edit_topics, name='edit_topic'),
And in html, change this line:
<form class="d-flex align-items-center" action="{% url 'learning_logs:edit_topic' form.instance.pk %}" method="POST">
^^^^^^^^^^^
Here, what I did is that, have 2 urls point to same view, one with topic_pk and another is without it.
I've been trying to create a movie survey in Django for an assignment, and I am currently working on the function. I can't seem to understand why won't it recognize the URL I pass.
I tried removing the hardcoded URL as shown in the Django tutorial on the framework's site, but that doesn't make the error go away.
Here's an excerpt from urls.py:
urlpatterns = [
url(r'^$', views.index, name="index"),
path('movie=<int:movie_id>&user=<int:user_id>/', views.movie, name='movie'),
path('ratings/', views.ratings, name='movie'),
path('rating/<int:movie_id>/', views.rating, name='movie'),
path('movie=<int:movie_id>&user=<int:user_id>/vote/', views.vote, name='vote'),
path('register/',views.register, name='register'),
]
This is my movie view( supposed to present a movie and a star rating radio for the user to rate the movie), where the URL is constructed and passed to HTML:
def movie(request,movie_id,user_id):
movie = get_object_or_404(Movie, pk=movie_id)
voteURL = '/polls/movie=' + str(movie_id) + '&user='+str(user_id)+'/vote/'
context = {
'mymoviecaption':movie.Title,
'moviePoster': 'https://image.tmdb.org/t/p/original'+tmdb.Movies(movie.TMDBID).images().get('posters')[0].get('file_path'),
'myrange': range(10,0,-1),
'myuserid':user_id,
'voteurl': voteURL,
'mymovieid':movie_id
}
#print(nextURL)
translation.activate('en')
return HttpResponse(render(request, 'movieview.html', context=context))
The HTML excerpt, where the vote view is called:
<form action="{% url voteurl %}" method="post">
{% for i in myrange %}
<input id="star-{{i}}" type="radio" name="rating" value={{i}}>
<label for="star-{{i}}" title="{{i}} stars">
<i class="active fa fa-star" aria-hidden="true"></i>
</label>
{% endfor %}
<input type="submit">Vote!</input>
</form>
The vote view( should save to database and redirect to the next movie, doesn't save to database yet, because I didn't want to clutter it with records until I am sure I got the function to work):
def vote(request, movie_id,user_id):
try:
nextmovie=get_object_or_404(Movie, pk=movie_id+1)
nextURL = '/polls/movie=' + str(movie_id + 1) + '&user='+str(user_id)+'/'
except Http404:
nextURL = '/polls/ratings'
try:
myrating = int(request.POST['rating'])
print(myrating)
except:
# Redisplay the question voting form.
return render(request, '/polls/movie=' + str(movie_id + 1) + '&user='+str(user_id)+'/', {
'error_message': "You didn't select a choice.",
})
return HttpResponseRedirect(nextURL)
No matter what I try, I get the NoReverseMatch at /polls/movie=1&user=9/ whenever I try to load the first movie page, despite said URL being defined in urlpatterns.
This is not the way how you provide two pk in the urls
It should be like this
path('movie/<int:movie_id>/<int:user_id>/', views.movie, name='movie'),
Also this is not the way of providing url in the template so it should be something like this
<form action="{% url 'vote' %}" method="post">
# {% url 'url_name' %}
# if app_name provided {% url 'app_name:url_name' %}
And please follow the tutorials step by step
I'm having trouble working with inherited code to make a functional search bar. I've been having the most trouble properly creating a search_results page.
I stripped down my search_results page to having only one line. search_results.html: <div>You searched for {{ query }}</div> but right now, the search_results page doesn't render {{ query }}. No text that the user previously entered appears. All that shows up on that page is "You searched for"
searchbox.html
<form class="search" action="{% url 'search' %}" method='post'>
{% csrf_token %}
<input type="search" placeholder="Search here..." name="usr_query"
value='{{ query }}' required>
<button type="submit">Search</button>
</form>
views.py
def search(request):
query = request.POST['usr_query']
print "QUERY: "
print query
t = loader.get_template('gtr_site/test_search_results.html')
c = Context({ 'query': query,})
return HttpResponse(t.render(c))
I was getting a little cautious and added that "print" statement... and it does print out what the user enters in the search bar. But that isn't being generated on my search_results page.
Whats the reasoning for this?
edit:
Adding urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^about/$', views.about, name='about'),
url(r'^contact/$', views.contact, name='contact'),
url(r'^search_engine/$', views.statement_search_engine, name='statement-search') # <- url for searchbox.html,
url(r'^test_search_results/$', views.search, name='test-search'), # <- url for searchresults.
url(r'^(?P<statement_id>.+)/$', views.statement_page, name='statement'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Change value='{{ request.GET.usr_query }}' to value="{{ query }}"
Right now you are forcing it to show the GET parameter. That works on initial page load (which is typically a GET) but at that point you haven't done any searching. You submit the search (properly in my opinion, but it is debatable) as a POST. The search function uses the POST parameter and returns in in context as query, which is correct. But then you display the GET value of usr_query - which does not exist at this point because the page is now a POSTed page. Change the value= and it should work.
Short answer:
Seems like this slipped by:
c = Context({ 'query': query,})
This is in views.py. Context() doesn't cause any error messages but... In order to get the functinality I needed, all I had to do was remove this function and make the c variable a regular dictionary.
I included the Context function because of this stackoverflow question Writing a very basic search form in Django
Your Searchbox.html method is a 'post' instead of a 'get'
<form class="search" action="{% url 'search' %}" method='get'>
{% csrf_token %}
<input type="search" placeholder="Search here..." name="usr_query"
value='{{ query }}' required>
<button type="submit">Search</button>
</form>
views.py
class search(ListView):
model = YourModel #The model model you want to search
template_name = 'gtr_site/test_search_results.html'
def get_queryset(self):
query = self.request.GET.get('usr_query')
object_list = YourModel.objects.filter(modelfield__icontains=query)
return object_list
The in your webpage probably index.html you should add the return.
{% for result in object_list %}
{{ result.name }}
{% endfor %}
I am facing 2 issues NoReverseMatch and APPEND_SLASH .
Issue #1. APPEND_SLASH
Detail.html
<form action="update-entry" method="post">
/* if I add '/' at the end of update-entry, it works fine. */
{% csrf_token %}
{{ form }}
<input type="submit" value="Edit">
</form>
When I click on the Edit button, I get the error below,
You called this URL via POST, but the URL doesn't end in a slash and you have
APPEND_SLASH set. Django can't redirect to the slash URL while maintaining
POST data. Change your form to point to 127.0.0.1:8000/genericviews/1/update-
entry/ (note the trailing slash), or set APPEND_SLASH=False in your Django
settings.
This is the URL generated:
http://127.0.0.1:8000/genericviews/1/update-entry
I know URL should end with '/'.
urls.py
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailsView.as_view(), name='detail'),
url(r'^makeentry$', views.makeentry, name='makeentry'),
url(r'^static/$', views.StaticView.as_view()),
url(r'^new-entry/$', views.MakeEntryView.as_view(), name='new-entry'),
url(r'^(?P<pk>[0-9]+)/update-entry/$', views.UpdateEntryView.as_view(), name='update-entry'),
]
My confusion is why URL is not generating '/' at the end. Above URL pattern seems correct to me.
Issue #2 NoReverseMatch
When I try to change the hardcoded URL, I get the error below,
NoReverseMatch at /genericviews/1/
Reverse for 'update-entry' with arguments '()' and keyword arguments '{}'
not found. 1 pattern(s) tried: ['genericviews/(?P<pk>[0-9]+)/update-
entry/$']
Detail.html
<form action="{% url 'genericviews:update-entry' %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Delete Product">
</form>
tried link as well,
{#Edit#}
When I click on any item from the page http://127.0.0.1:8000/genericviews/,
it takes me to the URL http://127.0.0.1:8000/genericviews/1/
And this is where it shows error.
I checked other answers, however, couldn't get it to work.
Any help would be appreciated.
It's not adding a slash because you haven't asked it to. You've hard-coded the relative URL of "update-entry", so that's what it will use.
When you do try and use the url tag, you get the error because you haven't passed the arguments it needs to generate that URL. Assuming you have the object in your template context as object, you would do:
{% url 'genericviews:update-entry' pk=object.pk %}