How to fix django appendslash runtime error? - django

So basically I have a pdf.html that is called upon by my view.
My form in the pdf.html is as follows:
<form action="{% url "soapdf:submitemail" %}" method="post">
{% csrf_token %}
{{ emailform }}
<input type="submit" value="Submit">
</form>
The corresponding function on views.py looks like this:
def submitemail(request):
if(request.method=='POST'):
return HttpResponse(request.POST['text_email'])
else:
return HttpResponse("false")
and my urls.py looks as follows:
app_name = 'soapdf' # use this to namespace the application so that you can use the url tagging scheme
urlpatterns = [
path('',views.get_pdf,name='get_pdf'),
path('submitemail/',views.submitemail,name='submitemail')
]
However on clicking the submit button I get the following error. My redirect has the slash but still doesnt work.
RuntimeError at /submitemail
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 localhost:8000/submitemail/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.
Any Ideas on how to fix this runtimeerror

Add trailing slash in your main urls.py where you have included this get_pdf urls
I think it's like
urlpatterns =[
path('get_pdf',include('yourapp.urls')),
]
and it will be
urlpatterns =[
path('get_pdf/',include('yourapp.urls')),
]

If SEO is not important, you can serve both with and without slash. In Django 3.X:
from django.urls import re_path
urlpatterns = [
re_path('^/?$',views.get_pdf,name='get_pdf'),
re_path('^submitemail/?$',views.submitemail,name='submitemail')
]
But if SEO is important, it is better to add slash automatically by Nginx or something else.

Related

NoReverseMatch Unless Url Is In Main Project Urls.py

I have a project called 'my_project' and within that project I have an app called 'my_app' so I have two urls.py files. All of my url's for my_app are located within it's urls.py file and work correctly, except one. That one is 'download_file'. My site works when this is included in my_project's urls.py, but when it's in my_app's urls.py I get a NoReverseMatch error on page load.
I don't know why this url only works when it's located in my main projects url's folder. I suspect it has something to do with the regex, though I can't figure it out.
The user would be on this page:
http://127.0.0.1:8000/user_area/username/classes
then click the 'download' link:
<a href="{% url 'download_file' file_path=item.instance.user_file %}" target='_blank'>{{ item.instance.filename }}</a>
my_project.py
urlpatterns = [
# reference to my_app
re_path(r'^user_area/(?P<username>[\w-]+)/', include('my_app.urls')),
]
# this works
url(r'^download_file/(?P<file_path>(.+)\/([^/]+))$', users_views.DownloadFile.as_view(), name='download_file'),
]
my_app.py
urlpatterns = [
path('classes', views.classes, name='classes'),
# if I remove the url from my_project.py this one returns NoReverseMatch on page load
url(r'^download_file/(?P<file_path>(.+)\/([^/]+))$', users_views.DownloadFile.as_view(), name='download_file'),
Thank you.
The problem is occurring because your URL template tag is providing only one parameter: file_path.
This works when the URL is declared in your project urls.py, because only one parameter is needed.
When you try to use the URL in my_app.urls, you need to also provide the username parameter. You will need to use something like:
<a href="{% url 'download_file' username=request.user.username file_path=item.instance.user_file %}" target='_blank'>{{ item.instance.filename }}</a>

Redirect to /admin/auth/user/ since my Django app

I'm looking for add a new reverse url in order to redirect to /admin/auth/user/ in my Django Admin page.
In my template, I already have : href="{% url "admin:index" %}" line which let to overcome to the admin page.
I would like to go directly to the users manage page and groups manage page respectively admin/auth/user/ and admin/auth/group.
My urls.py file looks like :
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name=os.path.join(settings.BASE_DIR, 'Accueil/templates/Choice.html')),
name='choice'),
url(r'^admin/', admin.site.urls),
url(r'^Identity/', include('Identity.urls')),
url(r'^Accueil/', include('Accueil.urls')),
url(r'^Home/', include('log.urls')),
url(r'^Informations/', include('Informations.urls')),
url(r'^Configurations/', include('Configurations.urls')),
url(r'^__debug__/', include(debug_toolbar.urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
How I can write href="{% url "admin:index" %}" in order to add user and group ? Up to now, I don't find a way to do that.
Thank you by advance
You can reverse the user and group changelist urls with:
{% url "admin:auth_user_changelist" %}
{% url "admin:auth_group_changelist" %}
See the docs on reversing admin urls for more info.

NoReverseMatch in render_to_response with django-social-auth

I would like to make just a page that has link to login to twitter/facebook/google with django-social-auth.
but I get a error NoReverseMatch: Reverse for '' with arguments '(u'twitter',)' and keyword arguments '{}' not found.
def index(request):
ctx = {}
return render_to_response('index_before_login.html', {}, RequestContext(request))
index_before_login.html is following
<li>Enter using Twitter</li>
urls.py is following
urlpatterns = patterns('',
url(r'^$', 'lebabcartoon.views.index'),
#url(r'^socialauth_', 'lebabcartoon.views.index'),
url('', include('social_auth.urls')),
my environment is
Django ver1.5
Python Version: 2.7.3
django-social-auth: 0.7.5
anyideas?
Wrap url name in quotes
{% url 'socialauth_begin' 'twitter' %}
To save someone using the new python-social-auth and django > 1.4
Use this :
{% url 'social:begin' 'twitter' %}
I had a similar problem, try adding the following to the url.py file in your project.
url(r'auth/', include('social_auth.urls'))
And also make sure your url parameters are wrapped in quotes like so.
{% url "socialauth_begin" "twitter" %}

Is it possible to pass query parameters via Django's {% url %} template tag?

I'd like to add request parameters to a {% url %} tag, like ?office=foobar.
Is this possible? I can't find anything on it.
No, because the GET parameters are not part of the URL.
Simply add them to the end:
<a href="{% url myview %}?office=foobar">
For Django 1.5+
<a href="{% url 'myview' %}?office=foobar">
A way to mix-up current parameters with new one:
{% url 'order_list' %}?office=foobar&{{ request.GET.urlencode }}
Modify your settings to have request variable:
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP
TEMPLATE_CONTEXT_PROCESSORS = TCP + (
'django.core.context_processors.request',
)
Use urlencode if the argument is a variable
<a href="{% url 'myview' %}?office={{ some_var | urlencode }}">
or else special characters like spaces might break your URL.
Documentation: https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#urlencode
First, a silly answer:
{% url my-view-name %}?office=foobar
A serious anwser: No, you can't. Django's URL resolver matches only the path part of the URL, thus the {% url %} tag can only reverse that part of URL.
If your url (and the view) contains variable office then you can pass it like this:
{% url 'some-url-name' foobar %}
or like this, if you have more than one parameter:
{% url 'some-url-name' office='foobar' %}
Documentation: https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#url
Tried all the above, nothing worked.
My system has:
Python 3.8.10
python3 -m django --version 4.0.3
Here's what worked for me:
urls.py
urlpatterns = [
path('', views.index, name='index'),
path('single/', views.single, name='single'),
]
views.py
def single(request):
url = request.GET.get('url')
return HttpResponse(url)
Calling from .html file
<a href={% url 'single' %}?url={{url}} target="_self">
Broswer URL
http://127.0.0.1:8000/newsblog/single/?url=https://www.cnn.com/2022/08/16/politics/liz-cheney-wyoming-alaska-primaries/index.html
Try this:
{% url 'myview' office=foobar %}
It worked for me. It basically does a reverse on that link and applies the given arguments.

Django reset_password_confirm TemplateSyntaxError problem

when I use django.contrib.auth.views.password_reset_confirm without arguments at all it works and I can render the template without any problem, when adding uidb36 and token arguments it fails.
Caught NoReverseMatch while rendering: Reverse for 'django.contrib.auth.views.password_reset_confirm' with arguments '()' and keyword arguments '{'uidb36': '111', 'token': '1111111111111'}' not found.
Most likely it is an issue with your urls.py. You need to setup the right pattern to grab the uidb36 and token values passed as URL parameters. If not, it will throw a similar error to what you see above.
Something like:
(r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', {'template_name' : 'registration/password_reset.html', 'post_reset_redirect': '/logout/' })
registration/password_reset.html - is my custom template
logout - is my custom logout action
I had this issue in Django 1.3, and wasted a lot of time because the error can mask a number of underlying issues.
I needed to add this to the top of the reset email template:
{% load url from future %}
Also, the example in the Django docs didn't match the sample url:
{{ protocol}}://{{ domain }}{% url 'auth_password_reset_confirm' uidb36=uid token=token %}
So I had to change the auth_password_reset_confirm above to password_reset_confirm.
If you're using Django 1.6+ and run into something like this it could be that you need to update uidb36 to uidb64 in both your template and your urls.
Example url:
url(r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
auth_views.password_reset_confirm
and reset link in template:
{{ protocol}}://{{ domain }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb64=uid token=token %}
For Django 1.8+ users, just copy this URL to your main urls.py file, so that it recognizes the URL name
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
'django.contrib.auth.views.password_reset_confirm',
name='password_reset_confirm'),
And add this mentioned by: #Lunulata to your password_reset_email.html file:
{{ protocol}}://{{ domain }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb64=uid token=token %}
Try adding following to your urls.py
(r'^reset/(?P<uidb36>[0-9A-Za-z]{1,13})-(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', 'django.contrib.auth.views.password_reset_confirm'),
I found this to work, copied from the default url
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
auth_views.password_reset_confirm, name='password_reset_confirm'),
Just add this line to your urls.py:
url('^', include('django.contrib.auth.urls')),
This enables the django reset_password workflow.
Then override your login.html to include the line:
<div class="password-reset-link">
href="{{ password_reset_url }}">{% trans 'Forgotten your password or username?' %}</a></div>
Now you should be able to use the builtin Django PasswordResetView included with Django as long as your email settings are set up.
if you are using app_name in every urls.py
suppose you have an app and in that app in urls.py you have mentioned app_name="accounts"
in order to retrieve the page you need to mention two things
template_name and success_url inside the PasswordResetView(template_name="accounts/password_reset.html" , success_url= reverse_lazy('accounts:password_reset_sent'))
dont forget to import reverse_lazy from django.urls inside urls.py
so your final code of accounts/urls.py should look like
My app name is landing instead of accounts
from django.urls import path
from . import views
from django.contrib.auth import views as auth_views
from django.urls import reverse_lazy
app_name='landing'
urlpatterns = [
path('',views.home,name="home"),
path('terms/',views.terms,name="terms"),
path('login/',views.loginUser,name="login"),
path('signup/',views.signupUser,name="signup"),
path('about/',views.about,name="about"),
path('logout/',views.logoutUser,name="logout"),
path('password_reset/',
auth_views.PasswordResetView.as_view(template_name='landing/password_reset.html',success_url=reverse_lazy('landing:password_reset_done')),
name="password_reset"),
path('password_reset_sent/',
auth_views.PasswordResetDoneView.as_view(template_name='landing/password_reset_sent.html'),
name="password_reset_done"),
path('reset/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(template_name='landing/password_reset_form.html',success_url=reverse_lazy('landing:password_reset_complete')),
name="password_reset_confirm"),
path('password_reset_complete/',
auth_views.PasswordResetCompleteView.as_view(template_name='landing/password_reset_done.html'),
name="password_reset_complete"),
]
you have to use app_name: before the name of url you have mentioned it is very important