Can't redirect using urls patterns - django

When i try go to http://127.0.0.1:8000/1395ec37e4/ i get error: Page not found at ...
I don't know why, twice, when i had changed variable getted_short_url to short_urlin urls.py and views.py(redirect_view) it could redirect me. I am confused...
Log from page:
Using the URLconf defined in cut_and_go.urls, Django tried these URL patterns, in this order:
<str:getted_short_url>
admin/
The current path, 1395ec37e4/, didn't match any of these.
views.py:
from hashlib import sha256
from .models import URL
from .forms import URLInput
from django.shortcuts import render, redirect
def input_form(request):
if request.method == 'POST':
form = URLInput(request.POST)
if form.is_valid():
getted_url = form.cleaned_data["full_url"]
transformed_url = 'https://' + getted_url
try:
URL.objects.get(full_url=transformed_url)
except URL.DoesNotExist:
maked_url = sha256(transformed_url.encode()).hexdigest()[:10]
URL(full_url=transformed_url, short_url=maked_url).save()
else:
form = URLInput()
return render(request, 'shortener/input_form.html', {'form': form})
def redirect_view(request, getted_short_url):
return redirect(URL.get_full_url(getted_short_url))
urls.py:
from . import views
from django.urls import path
urlpatterns = [
path('', views.input_form),
path('<str:getted_short_url>', views.redirect_view)
]

The str path converter does not catch the / character at the end of your URL. If you want to match only the part before the /, add a 2nd urlpattern (or replace the existing one if you don't care about URLs not ending with /) that includes the / at the end. If you want to catch this trailing slash in your path argument, use path instead of str. See Django docs for more information.

Related

Django writing view with sudomain

With my (Django v 1.17) project I am using django-subdomains.
I have no problem to call index view and when I open my url https://subdomain.domain.com I will get index.html.
My issue that I wrote a new view called example for the sub-domain but when I open the url https://subdomain.domain.com/exmaple I will get error Page not found (404).
Hete is my code:
settings.py
INSTALLED_APPS = [
'subdomain'
]
SUBDOMAIN_URLCONFS = {
'subdomain': 'subdomain.urls',
}
subdomain/urls.py
from django.conf.urls import url, include
from . import views
from django.contrib.auth import views as auth_views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^$example', views.example, name='example'),
]
subdomain/views.py
from django.shortcuts import render
from django.template import loader
from django.http import HttpResponse
def index(request):
template = loader.get_template('subdomain/index.html')
return HttpResponse(template.render())
def example(request):
template = loader.get_template('subdomain/example.html')
return HttpResponse(template.render())
Error:
Page not found (404)
Request Method: GET
Request URL: https://subdomain.domain.com/example
Using the URLconf defined in subdomain.urls, Django tried these URL patterns, in this order:
1. ^$ [name='index']
2. ^$example [name='example']
The current path, econ, didn't match any of these.
Please advise how to fix this issue and write view for sub-domain.
This is unrelated to django-subdomains. The dollar should be at the end of the regex.
url(r'^example$', views.example, name='example'),
The dollar matches the end of the string, so if you have it at the beginning then it's not going to match.

Separate domain for separate apps on django

I'd like to separate some apps on my website, and move some on differents domains.
But I'd like to avoid rewriting the urls in all the templates.
Is there an easy way to do this ?
The idea was to rewrite the reverse function (and thus, all the url dispatching thing).
Then, you have the first website called 'foo.com' and the second named 'bar.com'
This works for more sites than just two
app/urls.py
#!/usr/bin/python
# coding: utf-8
from django.conf.urls import include, url
from foo import urls as foo_urls
from bar import urls as bar_urls
url_patterns = [
url(r'^foo/',
include(foo_urls),
namespace='foo'),
url(r'^bar/',
include(bar_urls),
namespace='bar'),
]
app/__init__.py
#!/usr/bin/python
# coding: utf-8
"""
Just to simplify the multi website thing. Everything is served from one instance
"""
from __future__ import absolute_import
from django.core import urlresolvers
from django.http import Http404
from .settings LANGUAGES
old_reverse = urlresolvers.reverse
def remove_prefix(s, prefix):
return s[len(prefix):] if s.startswith(prefix) else s
def new_reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
""" Return an url with the domain if the page is situated on another domain
Note that this works for urls templatetags and for
django.core.urlresolvers.reverse, that are used a lot in get_absolute_url()
methods.
"""
old_reverse_url = old_reverse(viewname, urlconf, args, kwargs, current_app)
splitted_url = old_reverse_url.split('/')
if splitted_url[1] in [L[0] for L in LANGUAGES]:
(trash, lang, app, *path) = splitted_url
else:
(trash, app, *path) = splitted_url
lang = ''
if app == 'admin' or current_app == 'admin':
# fix a case where sometime the reverse has or has not a trailing /
old_reverse_url = remove_prefix(old_reverse_url, '/')
# fix a case where sometime the reverse has a double admin at the
# begining
old_reverse_url = old_reverse_url.replace('adminadmin', 'admin')
return '/%s' % old_reverse_url
path = '/'.join(path)
if lang == '':
return '//%s.com/%s' % (app, path)
else:
return '//%s.com/%s/%s' % (app, lang, path)
urlresolvers.reverse = new_reverse
templates examples
<a href="{% url 'foo:index' %}*>foo index</a>

Django reverse causing url circular import, why?

I get this error:
The included urlconf 'fouraxis.urls' does not appear to have any
patterns in it. If you see valid patterns in the file then the issue
is probably caused by a circular import.
I know the url pattern has something in it, it looks like this:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^perfil/', include('clientes.urls'), namespace="cliente"),
url(r'^admin/', include(admin.site.urls))
]
clientes.urls:
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from clientes import views
urlpatterns = [
# login
url(r'^login/$', auth_views.login, {'template_name': 'perfiles/login.html'}, name="login"),
url(r'^logout/$', auth_views.logout, {'template_name': 'perfiles/logged_out.html'}, name="login"),
url(r'^mi_perfil/$', views.mi_perfil, name="mi_perfil"),
url(r'^registro_usuario/$', views.RegistroUsuario.as_view(), name="registro_usuario")
]
The RegistroUsuario view looks like this:
class RegistroUsuario(FormView):
template_name = "perfiles/registro_usuario.html"
form_class = UserCreationForm
success_url = reverse("cliente:mi_perfil") # THIS REVERSE
def form_valid(self, form):
return redirect("cliente:mi_perfil")
context = {'form': UserCreationForm}
I understand I can replace the reverse with a plain-text url like this perfil/mi_perfil. But, I want to know why is this happening with reverse, I can't find the explanation on de docs. Also, using reverse is better cause it is dynamic (if anytime I change the url, it still works as long as it keeps its name).
The reverse() call is made when the view is imported, which is probably when the urlconf is first loaded. You need to use reverse_lazy() instead:
from django.core.urlresolvers import reverse_lazy
class RegistroUsuario(FormView):
template_name = "perfiles/registro_usuario.html"
form_class = UserCreationForm
success_url = reverse_lazy("cliente:mi_perfil") # THIS REVERSE
def form_valid(self, form):
return redirect("cliente:mi_perfil")
context = {'form': UserCreationForm}

Django Form Saving, but NOT Redirecting

Basis: I am trying to display a forms information with a new unique url as well as view upon submission. The form is currently saving to the database, but not redirection to the new url or view. Below I've posted both the views.py as well as the urls.py. If you need to see anything else please let me know.
Note: This is based off of a ModelForm and I am somewhat of a beginner to Django.
Thanks in advance!
url.py
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^letter/testing/$', 'letter.views.letter'),
url(r'^letter/testing/(?P<pk>\d+)/$','letter.views.submission'),
# Uncomment the admin/doc line below to enable admin documentation:
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
views.py
# Create your views here.
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from letter.forms import LetterForm
from letter.models import Letter
def submission(request, pk):
submission = get_object_or_404(Letter, pk=int(pk))
return render_to_response('post.html', {'submission':submission})
def letter(request):
if request.method == "POST":
letter = LetterForm(request.POST)
if letter.is_valid():
try:
new_letter = letter.save()
return HttpResponseRedirect('/letter/testing/%d/' % new_letter.pk)
except:
pass
else:
letter = LetterForm()
return render_to_response('letter.html',
{'letter':letter},
context_instance=RequestContext(request))
ANSWER:
Needed to remove the try/except parameters under if letter.is_valid()
Thank you #mattg!
Needed to remove the try and except parameters under if letter.is_valid()

Django response redirect on variable url

I'm on a page with a variable url /emails/edit/32/, and I want to update the form and refresh the page...how do I issue an HttpResponseRedirect to the current page, which has a variable extension?
My urls.py is:
urlpatterns = patterns('',
(r'^emails/edit/$', 'email_edit'), # this is the page it is re-directing to
(r'^emails/edit/(?P<email_id>\d+)/$', 'emails_single'),
)
And my views.py is:
def emails_single(request, email_id):
...(stuff)...
Email.objects.filter(id=request.POST['id']).update(email=request.POST['email'])
return HttpResponseRedirect(reverse('emails_single',args=[email_id]))
Update: what it is doing is just chopping off the ending of the URL (even when using the reverse examples). For example: http://127.0.0.1:8000/emails/edit/42/ --> http://127.0.0.1:8000/emails/edit/
from django.core.urlresolvers import reverse
return HttpResponseRedirect(reverse('emails_single', args=[email_id]))
reverse()
from django.core.urlresolvers import reverse
def myview(request):
return HttpResponseRedirect(reverse('urlname', args=[1945]))