I'm working on a site that would display some data on my database and a form where people can contact me.
views.py
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from .forms import ContactForm
from django.utils import timezone
from .models import Logo, SkillLanguages, SkillAPI, SkillFrameworks,
WorkPortfolio, PersonalPortfolio
def index(request):
logo=Logo.objects.all()
skill_languages=SkillLanguages.objects.all()
skill_api=SkillAPI.objects.all()
skill_frameworks=SkillFrameworks.objects.all()
work_portfolio=WorkPortfolio.objects.all()
personal_portfolio=PersonalPortfolio.objects.all()
return render(request, 'johann/index.html', {'logo': logo, 'skill_languages': skill_languages, 'skill_api': skill_api, 'skill_frameworks': skill_frameworks, 'work_portfolio': work_portfolio, 'personal_portfolio': personal_portfolio})
def email(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
try:
send_mail(name, message, from_email, ['myemail#notsuspiciousmailserver.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('success')
return render(request, "johann/index.html", {'form': form})
def success(request):
return HttpResponse('<script>alert("Success! Thank you for your message."); window.location = "https://pqdrl7qd.apps.lair.io/#contact";</script>')
urls.py
from django.conf.urls import include, url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^$', views.email, name='email'),
url(r'^success/$', views.success, name='success'),
]
I found out that my problem lies in what I did to the first two URLs, if I switched the email URL and the index URL's places my template would then display my form instead of the data stored in my models and vice versa. What can I do about this?
You have two url patterns that are identical
url(r'^$', views.index, name='index'),
url(r'^$', views.email, name='email'),
They will be evaluated in order and the index view will always match first. Once a match is found, the rest of the url patterns are ignored.
You need to come up with a different route for your email view. Might I suggest
url(r'^email/$', views.email, name='email'),
You can use:
url(r'^$', views.index, name='index'),
url(r'^email/$', views.email, name='email'),
Related
This is a book exchange system I'm trying to create. The challlenge I'm having is trying to redirect the user to a dynamic url consisting of there personal details after log in.
Here is my urs.py for my project
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('exchange/',include('exchange.urls')),
path('accounts/', include('django.contrib.auth.urls')),
path('admin/', admin.site.urls),
]
Here is my urs.py for my app
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
path('', views.base, name='base'),
path('register/', views.register_request, name='register'),
path('accounts/<int:id>/', views.user_view, name='userview'),
#path('login/', views.login_request, name='login'),
path('login/', auth_views.LoginView.as_view(template_name='exchange/login.html', redirect_field_name='user_view')),
]
Here is my views.py for my app
from django.shortcuts import render, redirect
from exchange.forms import user_login_form, user_register_form
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.contrib import messages
# Create your views here.
#Base index view
def base(request):
return render(request, 'exchange/base.html',{})
#registration view
def register_request(request):
if request.method=='POST':
form = user_register_form(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = User.objects.create_user(username=username, email=email, password=password)
user.save()
return redirect('login')
else:
messages.error(request, 'Invalid form')
render(request, 'exchange/register.html',{'form':form})
else:
form = user_register_form()
return render(request, 'exchange/register.html',{'form':form})
#login view
def login_request(request):
if request.method=='POST':
form = user_login_form(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect('user_view', id=user.id)
else:
messages.error(request, 'Invalid username or password')
render(request, 'exchange/login.html',{'form':form})
else:
messages.error(request, 'Invalid form')
render(request, 'exchange/login.html',{'form':form})
form = user_login_form()
return render(request, 'exchange/login.html',{'form':form})
#userview
def user_view(request, id):
user = User.objects.get(id=id)
return render(request, 'exchange/user_view.html',{'user':user})
I have also added LOGIN_REDIRECT_URL = '/accounts/int:id/' to my settings.py.
I presume your app is called exchange
because you've put this 'accounts/<int:id>' inside your exchange app's urls, it's actually trying to match for 'exchange/accounts/<int:id>'
path('exchange/',include('exchange.urls')),
# Link App's Urls -> 'exchange/{x}'.format(pattern)
# exchange.urls (prepend 'exchange')
# url: exchange
path('', views.base, name='base'),
# url: exchange/register
path('register/', views.register_request, name='register'),
# url: exchange/accounts/<int:id>
path('accounts/<int:id>/', views.user_view, name='userview'),
# etc
There's really no way around this prepending, so i think your best bet would be to put it in the main urls and just explicitly say what app + view
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
from exchange.views import user_view
urlpatterns = [
path('exchange/',include('exchange.urls')),
path('accounts/', include('django.contrib.auth.urls')),
path('accounts/<int:id>', user_view, name='userview'),
path('admin/', admin.site.urls),
]
I do not see your models but are you sure that you use user_id like
<int:id>
Normally I use pk like this
<int:pk>
You have the following name in your URLs.py
path('accounts/<int:id>/', views.user_view, ***name='userview'***),
But you are using a different name (with an underscore) in your redirect
return redirect(***'user_view'***, id=user.id)
They will need to match for the redirect to work
I have a question with my sites urls. When someone want to go mysite.com I redirect them to mysite.com/register.
url(r'^$', RedirectView.as_view(url='register/', permanent=False), name='index'),
url(r'^register/',views.guaform2,name='custform2'),
Also I have another url that allows to write somethings after the part of register. For example when someone goes to this website mysite.com/register/kh-54-m2-fc it allows to go that:
url(r'^register/(?P<pk>[-\w]+)',views.guaform,name='custform'),
But when I use these urls together my guaform view doesn't work. And it goes to customer_form2.html. When someone goes this site: mysite.com/register/ anything I want them go to customer_form.html. How can I seperate these urls?
urls.py
from django.conf.urls import url
from django.contrib import admin
from olvapp import views
from django.views.generic import RedirectView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', RedirectView.as_view(url='register/', permanent=False), name='index'),
url(r'^register/',views.guaform2,name='custform2'),
url(r'^register/(?P<pk>[-\w]+)',views.guaform,name='custform'),
]
views.py
from django.shortcuts import render,HttpResponse
from olvapp.models import Customer
from olvapp.forms import CustomerForm,CustomerForm2
from django.conf import settings
from django.http import HttpResponseRedirect
from django.urls import reverse
from olvapp import forms
def guaform(request,pk):
theurl = request.get_full_path()
orderid = theurl[10:]
form = CustomerForm(initial={'order_id':orderid})
if request.method == "POST":
form = CustomerForm(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect(reverse('thank'))
else:
HttpResponse("Error from invalid")
return render(request,'customer_form.html',{'form':form})
def guaform2(request):
form = CustomerForm2()
if request.method == "POST":
form = CustomerForm2(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect(reverse('thank'))
else:
HttpResponse("Error from invalid")
return render(request,'customer_form2.html',{'form':form})
It should be enough to lock down the regular expression so it doesn't match in both cases.
Tighten the custform2 regex by using an dollar sign on the end to mark the end of the input:
url(r'^register/$',views.guaform2,name='custform2'),
That should be enough to get things working
After filling the page should appear 'done', but i have an error message:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/candidate/done.html
The current path, candidate/done.html, didn't match any of these.
Can't configure redirect to 'done' page.
Here views.py:
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render, redirect
from .forms import AnketaForm
from .models import Anketa
def anketa_create_view(request):
if request.method == 'POST':
form = AnketaForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('candidate/done.html')
else:
form = AnketaForm()
return render(request, 'candidate/anketa_create.html', {'form': form})
urls.py (apps/candidate)
from django.urls import path
from . import views
urlpatterns = [
path('', views.anketa_create_view, name = 'anketa_create_view'),
]
urls.py
from django.contrib import admin
from django.urls import path, include
from candidate.views import anketa_create_view
urlpatterns = [
path('done/', anketa_create_view),
path('', anketa_create_view),
path('grappelli/', include('grappelli.urls')),
path('admin/', admin.site.urls),
]
you need to give a name to the done url
path('done/', anketa_create_view, name='done'),
and can do with reverse
return HttpResponseRedirect(reverse('done'))
or you can do redirect shortcut
return redirect('done')
Remove in urls.py
path('done/', anketa_create_view)
and replace in views.py
return HttpResponseRedirect('candidate/done.html')
to
return render(request, 'candidate/done.html', {})
found some topics like this but they are older or not solved.
Well, I'm following a youtube tutorial and I'm stuck in this part of it, I already know it's due the difference of version, I've gone to the docs and got some answers but still can't solve it by myself.
I'll post what I think it's relevant but if you guys want another part of my code ask and I'll get it.
the error as I said (on Traceback) is: NameError: name 'password_reset_done' is not defined
On the tutorial he didn't done anything on views.py about this, he just added some imports on url.py that was deprecated so I fix that but the errors keeps the same...
My accounts/urls.py:
from django.urls import path
from . import views
from django.contrib.auth.views import (
login,
logout,
password_reset,
PasswordResetDoneView,
PasswordResetConfirmView,
)
urlpatterns = [
path('', views.home),
path('login/', login, {'template_name': 'contas/login.html'}),
path('logout/', logout, {'template_name': 'contas/logout.html'}),
path('register/', views.register, name='register'),
path('perfil/', views.view_perfil, name='view_perfil'),
path('perfil/edit/', views.edit_perfil, name='edit_perfil'),
path('trocar-password/', views.trocar_password, name='trocar_password'),
path('reset-password/', password_reset, name='reset_password'),
path('reset-password/done/', password_reset_done, name='password_reset_done'),
path('reset-password/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/',
password_reset_confirm, name='password_reset_confirm'),
]
just to add some more code. My views.py:
from django.shortcuts import render, redirect, HttpResponse
from contas.forms import (
RegistrationForm,
EditPerfilForm,
)
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserChangeForm, PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
def home(request):
numbers = [1,2,3,4,5]
name = 'Lucas Cyrne'
args = {'myName': name, 'numbers': numbers}
return render(request, 'contas/home.html', args)
def register(request):
if request.method=='POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('/contas')
else:
form = RegistrationForm()
args = {'form':form}
return render(request, 'contas/reg_form.html', args)
def view_perfil(request):
args = {'user': request.user}
return render(request, 'contas/perfil.html', args)
def edit_perfil(request):
if request.method=='POST':
form = EditPerfilForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('/contas/perfil')
else:
form = EditPerfilForm(instance=request.user)
args = {'form': form}
return render(request, 'contas/edit_perfil.html', args)
def trocar_password(request):
if request.method=='POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect('/contas/perfil')
else:
return redirect('/contas/trocar_password')
else:
form = PasswordChangeForm(user=request.user)
args = {'form': form}
return render(request, 'contas/trocar_password.html', args)
Django looks for everywhere, and doesn't see password_reset_done
and above your urls patter, there is this:
NOTE: these built-in CBV are available forn Django >= 1.11
from django.contrib.auth.views import (
login,
logout,
password_reset, # suggestion: PasswordResetView
PasswordResetDoneView,
PasswordResetConfirmView,
)
you view is PasswordResetDoneView
instead of:
path('reset-password/done/', password_reset_done, name='password_reset_done'),
it should be:
path('reset-password/done/', PasswordResetDoneView.as_view(), name='password_reset_done'),
Cause you didn't call password_reset_done view, but using it in urls.
path('reset-password/done/', password_reset_done, name='password_reset_done'),
Look this url, you are trying to use view that doesn't exist.
Make your own view inheriting PasswordResetDoneView or, just use it without registering url. (You only can call url using password_reset_done like this
reverse('password_reset_done')
p.s. you have to add django.contrib.auth.urls to your urls.py. like
url('', include('django.contrib.auth.urls')), ( for django =< 1.11 )
You need to add app_name is urls.py
Add views as viewname.as_view() in urls.py
I'm experimenting with Django forms. I'm trying to create a form which will accept the name of a city as input and output coordinates as output. My apps name is rango. I'm having a lot of trouble in URL reverse after accepting the input of the form..
My project/urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf import settings
import os
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'mysite.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^rango/',include('rango.urls', namespace="rango")),
)
if settings.DEBUG:
urlpatterns += patterns(
'django.views.static',
(r'media/(?P<path>.*)',
'serve',
{'document_root': settings.MEDIA_ROOT}), )
My rango/urls.py (rango is the name of the app):
from django.conf.urls import patterns, url
from rango import views
urlpatterns = patterns('',
url(r'^welcome/$', views.index, name='index'),
url(r'^about/$', views.about, name='about_page'),
url(r'^categories/(?P<name_dir>\w+)/$',views.cats,name='cats'),
url(r'^disp_page/(?P<city>\w+)/$',views.geo,name='coods'),
url(r'^disp_page/$', views.disp_page, name='disp_page')
My forms.py:
from django import forms
from rango.models import Page, Category
class PageForm(forms.ModelForm):
title = forms.CharField(max_length=128, help_text="Please enter the name of the city.")
#url = forms.URLField(max_length=200, help_text="Please enter the URL of the page.")
#views = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
class Meta:
# Provide an association between the ModelForm and a model
model = Page
exclude = ('category','url','views')
My views.py:
from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext
from django.shortcuts import render_to_response
from rango.models import Category,Page
from pygeocoder import Geocoder
from rango.forms import PageForm
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
import operator
# Create your views here.
def geo(request,city):
context = RequestContext(request)
citydata=Geocoder.geocode(city)
codtuple=citydata[0].coordinates
codtuple=list(codtuple)
context_dict = {'cood':codtuple}
return render_to_response('coods.html',context_dict,context)
def disp_page(request):
# A HTTP POST?
if request.method == 'POST':
form = PageForm(request.POST)
# Have we been provided with a valid form?
if form.is_valid():
# Save the new category to the database.
#form.save(commit=True)
city = form.cleaned_data['title']
# context = RequestContext(request)
#citydata=Geocoder.geocode(cityname)
#codtuple=citydata[0].coordinates
#codtuple=list(codtuple)
#context_dict = {'cood':codtuple}
return HttpResponseRedirect(reverse('rango:geo', args=(request,city)))
else:
# The supplied form contained errors - just print them to the terminal.
print form.errors
else:
# If the request was not a POST, display the form to enter details.
form = PageForm()
# Bad form (or form details), no form supplied...
# Render the form with error messages (if any).
return render(request, 'disp_page.html', {'form': form})
Basically the disp_page displays the form. I type the name of a city in the form(EX:NEWYORK) and then it has to redirect to the "geo" function in my views.py which would output the coordinates in a different view. This redirection doesn't seem to be happening. Any help is appreciated!!
change this line
url(r'^disp_page/(?P<city>\w+)/$',views.geo,name='coods'),
in rango/urls.py to :
url(r'^disp_page/(?P<city>\w+)/$',views.geo,name='geo'),
and use :
return HttpResponseRedirect(reverse('rango:geo', args=(city,)))