URL name keeps appending to end Django - python

I am running into a few issues regarding URL mappings in Django. I have the following code:
table.html:
<form id="filter_form" method="post" action="update_filters/">
<input type="submit" name="submit" value="Report" />
</form>
urls.py:
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^update_filters/', views.filter_report, name='update_filters'),
]
views.py:
def filter_report(request):
# Code in the function
return render(request, 'autotester/table.html', context)
and everything works, but when I hit the "Report" button multiple times I get:
127.0.0.1:8000/autotester/update_filters
127.0.0.1:8000/autotester/update_filters/update_filters
127.0.0.1:8000/autotester/update_filters/update_filters/update_filters
etc
and I have no idea what's causing it. There has to be some sort of simple fix for this but I just can't find it and I have been trying to figure this out for 3 hours now and my brain is just fried.

Try using {% url 'update_filters' %} template tag. And also add $ at the end of the regular expression in your url definition.
url(r'^update_filters/$', views.filter_report, name='update_filters'),

Related

Django Error: NoReverseMatch at / ; looking at wrong urlpattern?

I am simply trying to open the web app to the home page, but at startup I am given the NoReverseMatch error message. The full message is the following: Reverse for 'wiki' with no arguments not found. 1 pattern(s) tried: ['wiki/(?P<title>[^/]+)/$']. In case it's relevant, I am using Django version 3.2.4.
In urls.py for my project I have:
urlpatterns = [
path('', include("encyclopedia.urls", namespace="encyclopedia")),
path('admin/', admin.site.urls),
]
In urls.py for my app I have:
app_name = "encyclopedia"
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<title>/", views.entry, name="wiki"),
.... (rest omitted for brevity)
]
In views.py I have:
def index(request):
context = {
"entries": ["item1", "item2", "item3"],
"form": SearchForm(),
}
return render(request, "encyclopedia/index.html", context)
In index.html, I have:
{% block body %}
<h1>All Pages</h1>
<ul>
{% for entry in entries %}
<li>
<form action="{% url 'encyclopedia:wiki' %}", method="POST">
{% csrf_token %}
<input type="text" value="{{ entry }}" name="link" hidden>
<input type="submit" class="link-btn" value="{{ entry }}" style="border: 0; background-color: white">
</form>
</li>
{% endfor %}
</ul>
{% endblock %}
As the error message indicates, it appears to be looking at the url pattern named wiki, and then subsequently failing to find the arguments passed to it. However, I am not trying to check that pattern; it should be going to the default pattern of path("", views.index, name="index"), not the wiki one. The wiki one works fine, by the way, as when I go the url wiki/<title>/, it loads fine. The rest of the app works fine as well. The other odd thing is that the index path worked fine before I added the arguments to the wiki url (path("wiki/<title>/", views.entry, name="wiki"),).
I have been looking at other SO posts that deal with this issue, and have followed the debugging advice given in this post, as well as this article, and none of the solutions apply/seem to work; this happens on app startup so there is no link being clicked to begin with, there are no comments it could be reading instead, it's not supposed to be calling wiki in the first place so the key word arguments are irrelevant, and the namespace is set in the project's urls.py. In summary, the issue appears to be that, upon start up of the app, it should be looking at the name "index" in the first path(), and then calling the appropriate function, but it is instead looking at the name "wiki" and expecting arguments.
If anyone can figure out how I can fix this problem, I would be very grateful!

Cannot resolve NoReverseMatch error in Django

I am new in Django and try to make a quick search engine, but I have this error and cannot fix it after reading Django documentation. Could anyone help me? Thanks.
This is the error:
Reverse for 'search' with no arguments not found. 1 pattern(s) tried: ['(?P<name>[^/]+)$']
My codes are as below:
layout.html
<form method="POST" action="{% url 'encyclopedia:search' %}">
{% csrf_token %}
<input class="search" type="text" name="q" placeholder="Search Encyclopedia">
<input type="submit" value="Go">
</form>
urls.py
from django.urls import path
from . import views
app_name = "encyclopedia"
urlpatterns = [
path("", views.index, name="index"),
path("<str:name>", views.entry, name="entry"),
path("<str:name>", views.search, name="search")
]
views.py
def search(request, searched_name):
"""
Deal with search engine on the left widget
"""
result = util.get_entry(searched_name)
if result:
return HttpResponseRedirect(reverse('encyclopedia:entry', args=(result)))
return render(request, "encyclopedia/error.html", {
"error_name": "Requested page not found"
})
Your second and third urls the same that's why only one pattern is tried and given the pattern named search isn't the first one, django is unable to find a reverse match. The URLs aren't well thought as they will both match any string after the root of the domain and this will definitely become a nightmare as your project grows bigger. Consider having them as below:
urlpatterns = [
...
path("entry/<str:name>", views.entry, name="entry"),
path("search/<str:name>", views.search, name="search")
]
As per your urls.py, you need to name in URL itself.
I will suggest you to remove name from urls.py and get in views via form data. Please see an example below
urls.py -> path("search/", views.search, name="search")
def search(request):
"""
Deal with search engine on the left widget
"""
result = util.get_entry(request.POST.get('q', None))
if result:
return HttpResponseRedirect(reverse('encyclopedia:entry', args=(result)))
return render(request, "encyclopedia/error.html", {
"error_name": "Requested page not found"
})

django parameter causing the wrong template and view to render

Overview / Problem:
Hi! The wrong template and view are loading every time I click the check_tier_level link in my template.
When that parameter is in, it loads the home view with "check_tier_level" as the special_message, even though my links go to the view for check_tier_level. If I click any of the form buttons to grant access, the proper message shows up in that spot. I just can't check the level.
The app works fine and renders the right template / view only when I remove the special_message parameter from the urlpattern and view.
The only other lead I have on this is that the url in the browser will also look like http://127.0.0.1:8000/tiered_access_app/Tier 1 granted!/, instead of having the characters escaped with %20 and so on.
My goal
The whole reason I want to keep that parameter in is so a special_message can notify users of the latest update based on their actions. If anyone knows a better way to do this without making a whole new view / template (which I know is a solution, and how to do it), I'd like to know how. Anyways, here's my code:
urlpatterns.py
path('', views.home, name='home'),
path('<str:special_message>/', views.home, name='home_special_message'),
path('check_tier_level/', views.check_tier_level, name='check_tier_level'),
path('check_tier_level/gain_access/', views.gain_access, name='gain_access'),
views.py
def home(request, special_message=None):
return render(request, 'tiered_access_app/home.html', {'special_message': special_message})
def check_tier_level(request):
current_user = request.user
try:
find_user = TieredAppCustomUser.objects.get(user=current_user)
if find_user.tier_choice == 'tier1':
return render(request, 'tiered_access_app/check_tier_level.html', {'level_1': 'You have access to level 1.'})
# and so on with other levels...
except ObjectDoesNotExist:
pass
return render(request, 'tiered_access_app/check_tier_level.html', {'no_access': 'You don\'t have access to the content here yet.'})
home.html
{% if special_message %}
<h2>{{ special_message }}</h2>
{% endif %}
<form action="{% url 'tiered_access_app:gain_access' %}" method="POST">
{% csrf_token %}
<label>Check level 1 access</label>
<!-- *******PROBLEM WITH LINK HERE******** -->
<p>Try to access level 1 first. You won't be allowed unless you gain access first, by clicking the button below.</p>
<!-- *******PROBLEM WITH LINK HERE******** -->
<input type="hidden" value='1' name="tier_level">
<input type="submit" value="Enable level 1">
</form>
I FIGURED IT OUT:
All I had to do was change my url patterns into the following order:
path('', views.home, name='home'),
path('check_tier_level/', views.check_tier_level, name='check_tier_level'),
path('check_tier_level/gain_access/', views.gain_access, name='gain_access'),
path('<str:special_message>/', views.home, name='home_special_message'),
The only difference here and what I have below, is the position of the 2nd function that goes to home. I'm going to leave this question up in case someone else comes across this same problem. I don't know why this made it work, but it did. Now everything works perfectly.

Django NoReverseMatch and POST URL error

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 %}

NoReverseMatch during render

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

Categories

Resources