Django NoReverseMatch URL redirect - python

I am trying to customize the signup redirect url using allauth in django 3. I am getting this error, instead:
NoReverseMatch at /accounts/candidate-signup/
Reverse for 'candidate_profile' with no arguments not found. 1 pattern(s) tried: ['accounts/profile/(?P<username>[^/]+)/$']
views.py
from django.shortcuts import render
from django.views import View
from .models import CandidateProfile
from .forms import CandidateProfileForm
from allauth.account import app_settings
from allauth.account.views import SignupView
from allauth.account.utils import complete_signup
from allauth.exceptions import ImmediateHttpResponse
class CandidateSignUpView(SignupView, View):
def get(self, request, *args, **kwargs):
form = self.form_class(request.POST)
return render(request, self.template_name, {'form': form})
def form_valid(self, form):
self.user = form.save(self.request)
self.user.is_candidate = True
self.user.save()
success_url = f'profile/{self.user.username}/'
try:
return complete_signup(
self.request,
self.user,
app_settings.EMAIL_VERIFICATION,
self.success_url,
)
except ImmediateHttpResponse as e:
return e.response
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('candidate-signup/', views.CandidateSignUpView.as_view(), name='candidate_signup'),
path('company-signup/', views.CompanySignUpView.as_view(), name='company_signup'),
path('profile/<str:username>/', views.CandidateProfileView.as_view(), name='candidate_profile'),
]
django/conf/global_settings.py
LOGIN_REDIRECT_URL = 'candidate_profile'
html
<form class="signup" id="signup_form" method="post" action="{% url 'candidate_signup' %}">
{% csrf_token %}
{{ form.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
A working solution would redirect from the signup page to /accounts/profile/<str:username>/

You have two issues in CandidateSignUpView:
You're passing self.success_url to complete_signup, instead of passing success_url, which is defined locally in form_valid method. As self.success_url is None (it is defined in SignupView and inherited in your CandidateSignUpView), complete_signup is receiving None for success_url parameter, so it uses default success_url after login.
You should better not construct urls manually. For this you'd better use reverse and pass view name and according arguments, so instead of success_url = f'profile/{self.user.username}/' you'd better use success_url = reverse('candidate_profile',kwargs={'username':self.user.username}). See more about reverse here.
So, your CandidateSignUpView should be something like this:
from django.shortcuts import render
from django.views import View
from .models import CandidateProfile
from .forms import CandidateProfileForm
from allauth.account.views import SignupView
from allauth.account.utils import complete_signup
from allauth.exceptions import ImmediateHttpResponse
from django.http.response import HttpResponse
from django.urls.base import reverse
class CandidateSignUpView(SignupView, View):
def get(self, request, *args, **kwargs):
form = self.form_class(request.POST)
return render(request, self.template_name, {'form': form})
def form_valid(self, form):
self.user = form.save(self.request)
self.user.is_candidate = True
self.user.save()
# success_url = f'profile/{self.user.username}/'
success_url = reverse('candidate_profile',kwargs={'username':self.user.username})
try:
return complete_signup(
self.request,
self.user,
app_settings.EMAIL_VERIFICATION,
# self.success_url,
success_url
)
except ImmediateHttpResponse as e:
return e.response

Related

Django class-based form with dropdowns populated with data from model / db

This my Django code:
forms.py
from django import forms
class MyForm(forms.Form):
name = forms.CharField()
location = forms.CharField()
views.py
class MyFormView(FormView):
template_name = 'form.html'
form_class = MyForm
success_url = 'home'
def get(self, request, *args, **kwargs):
form = self.form_class
return render(request, 'form.html', {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
return render(request, self.template_name, {'form': form})
template form.html
<form method="post" action="{% url 'form' %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-primary btn-block py-2" value="OK">
</form>
models.py
class MyModel(models.Model):
# ...
name = models.OneToOneField(Person, on_delete=models.CASCADE))
location = models.ForeignKey(Location, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
# ...
I want both two fields (name, location) to be drop-downs (combobox-es) not CharFields, and I want to populate their entries / values with data coming from db (django models). How can I do that? I am completely new to CBV idea.
You should use ModelChoiceField instead of CharField so:
from django import forms
from .models import YourModelName
class ReleaseForm(forms.Form):
name = forms.ModelChoiceField(queryset=YourModelName.objects.all())
location = forms.ModelChoiceField(queryset=YourModelName.objects.all())
Form class doesn't have a save() method unlike modelforms so you should manually save the form using cleaned_data in form_valid() method as:
from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.views.generic import FormView
from .forms import MyForm
from .models import MyModel
class MyFormView(FormView):
template_name = 'form.html'
form_class = MyForm
success_url = reverse_lazy('home')
def form_valid(self, form):
name = form.cleaned_data['name']
location = form.cleaned_data['location']
MyModel.objects.create(name=name, location=location)
return super().form_valid(form)

I Want to store the form data to the database

I want store the form data into database ('subject_code' is the table name or model name) but when I press the submit button its throwing an error
the error is
TypeError at /subjectnamewithcode/
_wrapped_view() missing 1 required positional argument: 'request'
please help me.
this is my view.py
from django.conf.urls import url, include
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.forms import User
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin
# Create your views here.
from .models import signupform, Universityname, facultyhours, subject_code, class_number
def home(request):
count=User.objects.count()
return render(request, 'home.html', {
'count':count
})
def signup(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
usernamedb=request.POST['username']
passworddb=request.POST['password1']
emaildb=request.POST['email']
signup_info=signupform(usernamedb=usernamedb,passworddb=passworddb,emaildb=emaildb)
signup_info.save()
form.save()
return redirect('home')
else:
form = UserCreationForm()
return render(request, 'registration/signup.html', {
'form': form
})
#login_required()
def secret_page(request):
return render(request, 'secret_page.html')
class SecretPage(LoginRequiredMixin,TemplateView):
template_name = 'secret_page.html'
#login_required()
def University_names(request):
return render(request, 'createtimetable/university_or_collegename.html')
#login_required()
def universityNames_store_in_database(request):
university_name=request.POST["universityname"]
Department_id=request.POST["departmentid"]
Department_name=request.POST["departmentname"]
university_dept_info=Universityname(university_name=university_name,Department_id=Department_id,Department_name=Department_name)
university_dept_info.save()
return redirect('/faculty_hours/')
#login_required()
def faculty_hours(request):
return render(request, 'createtimetable/faculty_hours.html',)
#login_required()
def map_faculty_with_hours(request):
faculty_name=request.POST["facultyname"]
faculty_unique_name=request.POST["facultyuniquname"]
faculty_total_hours_in_a_week=request.POST["facultytotalnumberofhours"]
map_faculty_with_hours_db=facultyhours(faculty_name = faculty_name, faculty_unique_name = faculty_unique_name, faculty_total_hours_in_a_week = faculty_total_hours_in_a_week)
map_faculty_with_hours_db.save()
return render(request, 'createtimetable/faculty_hours.html')
#login_required()
def subject_code(request):
return render(request, 'createtimetable/subjects_code.html')
def subjectnamewithcode(request):
subject_name=request.POST["subjectname"]
subject_id=request.POST["subjectcode"]
subjectnamewithcodedb=subject_code(subject_name = subject_name, subject_id = subject_id)
subjectnamewithcodedb.save()
return render(request, 'createtimetable/subjects_code.html')
#login_required()
def class_number(request):
return render(request, 'createtimetable/class_number.html')
#login_required()
def class_with_numbers(request):
class_name=request.POST["classname"]
class_number1=request.POST["classroomnumber"]
class_with_number_db=class_number(class_name=class_name,class_number=class_number1)
class_with_number_db.save()
return render(request, 'createtimetable/class_number.html')
#login_required()
def userdetails(request):
# allusers=signupform.objects.all()
return render(request, "secret_page.html")#, {'uusers': allusers})
this is my model.py
from django.db import models
# Create your models here.
class signupform(models.Model):
usernamedb=models.CharField(max_length=250)
passworddb=models.CharField(max_length=250)
emaildb=models.CharField(max_length=250)
class Universityname(models.Model):
university_name=models.CharField(max_length=250)
Department_name=models.CharField(max_length=250)
Department_id=models.CharField(max_length=250)
class facultyhours(models.Model):
faculty_name=models.CharField(max_length=250)
faculty_unique_name=models.CharField(max_length=250)
faculty_total_hours_in_a_week=models.CharField(max_length=250)
class subject_code(models.Model):
subject_name=models.CharField(max_length=250)
subject_id=models.CharField(max_length=250)
class class_number(models.Model):
class_name=models.CharField(max_length=250)
class_number=models.CharField(max_length=250)
this is my urls.py
from django.contrib import admin
from django.urls import path, include
from mysite.core import views
urlpatterns = [
path('', views.home, name='home'),
path('signup/', views.signup, name='signup'),
path('secret/',views.secret_page, name='secret' ),
path('secret2/', views.SecretPage.as_view(), name='secret2'),
path('accounts/', include('django.contrib.auth.urls')),
path('University_names/', views.University_names, name='University_names'),
path('universityNames_store_in_database/', views.universityNames_store_in_database, name='universityNames_store_in_database'),
path('faculty_hours/', views.faculty_hours, name='faculty_hours'),
path('map_faculty_with_hours/', views.map_faculty_with_hours, name='map_faculty_with_hours'),
path('subject_code/', views.subject_code, name='subject_code'),
path('subjectnamewithcode/', views.subjectnamewithcode, name='subjectnamewithcode'),
path('class_number/', views.class_number, name='class_number'),
path('class_with_numbers/', views.class_with_numbers, name='class_with_numbers'),
path('admin/', admin.site.urls),
]
this is my html form
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row justify-content-center">
<div class="col-6">
<div class="card">
<div class="card-body">
<h2>Mapping Subject And Code</h2>
<form method="post" action="/subjectnamewithcode/">
{% csrf_token %}
{{ form|crispy }}
<label>Add Subject</label><br>
<input type="text" name="subjectname" required class="textinput textInput form-control"><br>
<label>Subject Code</label><br>
<input type="text" name="subjectcode" required class="textinput textInput form-control"><br>
<button type="submit" class="btn btn-primary">ADD</button>
NEXT
</form>
</div>
</div>
</div>
</div>
{% endblock %}
This error I am getting
TypeError at /subjectnamewithcode/
_wrapped_view() missing 1 required positional argument: 'request'
Request Method: POST
Request URL: http://127.0.0.1:8000/subjectnamewithcode/
Django Version: 2.2.4
Exception Type: TypeError
Exception Value:
_wrapped_view() missing 1 required positional argument: 'request'
Exception Location: /Users/vajra/Documents/DJANGO/mysite/core/views.py in subjectnamewithcode, line 88
Python Executable: /Users/vajra/Documents/DJANGO/venv/bin/python
Python Version: 3.7.3
Python Path:
['/Users/vajra/Documents/DJANGO',
'//miniconda3/lib/python37.zip',
'//miniconda3/lib/python3.7',
'//miniconda3/lib/python3.7/lib-dynload',
'/Users/vajra/Documents/DJANGO/venv/lib/python3.7/site-packages']
Server time: Wed, 4 Sep 2019 17:40:43 +0000
Traceback Switch to copy-and-paste view
/Users/vajra/Documents/DJANGO/venv/lib/python3.7/site-packages/django/core/handlers/exception.py in inner
response = get_response(request) …
▶ Local vars
/Users/vajra/Documents/DJANGO/venv/lib/python3.7/site-packages/django/core/handlers/base.py in _get_response
response = self.process_exception_by_middleware(e, request) …
▶ Local vars
/Users/vajra/Documents/DJANGO/venv/lib/python3.7/site-packages/django/core/handlers/base.py in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
▶ Local vars
/Users/vajra/Documents/DJANGO/mysite/core/views.py in subjectnamewithcode
subjectnamewithcodedb=subject_code(subject_name = subject_name, subject_id = subject_id) …
▶ Local vars

Forbidden (403) CSRF verification failed. Request aborted.in Django

Why does Django show this error: 'Forbidden (403)CSRF verification failed. Request aborted.' when I already have {% csrf_token %} in the form.
templates/core/signup.html
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>
{% endblock %}
views.py
from django.contrib.auth.forms import UserCreationForm
from django.views.generic.edit import CreateView
class SignUpView(CreateView):
template_name = 'core/signup.html'
form_class = UserCreationForm
Since you are already passing on the csrf token from django.core.context_processors.csrf to the context manager. Check whether the form HTML has something like this or not:
<input type='hidden' name='csrfmiddlewaretoken' value="jqhdwjavwjagjzbefjwdjqlkkop2j3ofje" />
A couple of other things are required to make the csrf protection work (check out the docs):
Your browser has to accept cookies from your server
Make sure you have 'django.middleware.csrf.CsrfViewMiddleware' included as middleware in your settings.py (alternatively use the decorator csrf_protect() on particular views you want to protect)
In your views.py you need to pass the RequestContext in your render_to_response for the context processors to actually be run.
from django.template import RequestContext
context = {}
return render_to_response('my_template.html',
context,
context_instance=RequestContext(request))
the new render shortcut (django 1.3+) will do it for you:
from django.shortcuts import render
context = {}
return render(request, 'my_template.html', context)
For class-based view:
class MyFormView(View):
form_class = MyForm
initial = {'key': 'value'}
template_name = 'form_template.html'
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
# <process form cleaned data>
return HttpResponseRedirect('/success/')
return render(request, self.template_name, {'form': form})

how to handle httpresponseredirect

test2/urls.py
from django.conf.urls import url
from .import views
from .forms import forms
urlpatterns=[
url(r'^$',views.index,name='index'),
url(r'^thankyou/$',views.thankyou,name='thankyou')
]
test1/urls.py
from django.contrib import admin
from django.conf.urls import url , include
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test2/',include('test2.urls')),
]
views.py
this view should redirect to /test2/thankyou/ but why it is going to /thankyou
and what to do enable the view given by redirect method
from django.shortcuts import render
from django.http import HttpResponseRedirect,HttpResponse
from .forms import Get_name
# Create your views here.
def index(request):
if request.method == 'POST':
form = Get_name(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thankyou/')
else:
form = Get_name()
return render(request, 'test2/name.html' , {'form':form})
def thankyou(request):
return HttpResponse('sai chaitanya')
name.html
after submitting the form it should redirect to test2/thankyou but it is going to /thankyou.
<form action="/thankyou/" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
forms.py
from django import forms
user_choice =[('space',''),('passenger','Passenger'),('driver','Driver')]
class Get_name(forms.Form):
user_name = forms.CharField(label='user name',max_length='50',required=True)
pass_word1 = forms.CharField(widget=forms.PasswordInput,max_length='20',label='Password')
pass_word2 = forms.CharField(widget=forms.PasswordInput, max_length='20', label='Confirm Password')
email = forms.EmailField(label='email',max_length='100')
mobile = forms.CharField(label='contact number ',widget=forms.NumberInput,max_length='10')
address = forms.CharField(label='Address',max_length='100')
user_type = forms.CharField(label='select user type',widget=forms.Select(choices=user_choice))
It is going to /thankyou/ because you have hardcoded the URL /thankyou/:
return HttpResponseRedirect('/thankyou/')
You can redirect to /test2/thankyou/ by changing the code to:
return HttpResponseRedirect('/test2/thankyou/')
However the best practice is to reverse the URL instead of hardcoding it:
from django.urls import reverse
return HttpResponseRedirect(reverse('thankyou'))
This can be simplified using the redirect shortcut:
from django.shortcuts import redirect
return redirect('thankyou')

How to properly address a modified Django login form in the template files using crispy forms?

I have a modified Django login form and I have to address it in the template file using the long model like this {% crispy formname formname.helper %}. I can't use the short version ({% crispy form %}) because I have to differentiate between multiple forms. The thing is, all works well for normal forms, but not for a modified Django login form.
The code goes like this:
forms.py
from crispy_forms.helper import FormHelper
from django.contrib.auth.forms import AuthenticationForm
class LoginForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'login-form'
self.helper.form_show_labels = False
self.helper.layout = Layout(
Field('username', placeholder="E-mail"),
Field('password', placeholder="Password")
)
self.helper.add_input(Submit('submit', 'Log in', css_class='btn-block btn-inset'))
views.py
from django.contrib.auth import authenticate, login as auth_login, REDIRECT_FIELD_NAME
from django.contrib.auth.views import login as django_login
from accounts.forms import LoginForm
from django.http import HttpResponseRedirect
def login(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/profiles/create/')
else:
response = django_login(request, template_name='accounts/login.html', authentication_form=LoginForm)
return response
When I try to address it in the template in the form of {% crispy response response.helper %} I only get an error stating VariableDoesNotExist at /accounts/whateverurl/: Failed lookup for key [response].
How should I address it?
Django 1.6
EDIT:
The solution works when I want to call the login form from that particular view, but when I try to call it from profiles/views.py, not so much.
The profiles/views.py looks like this:
from django.contrib.auth import authenticate, login as auth_login, REDIRECT_FIELD_NAME
from django.contrib.auth.views import login as django_login
from django.views.generic import DetailView
from accounts.forms import LoginForm, RegisterForm
from accounts.views import get_redirect_url
class ProfileView(DetailView):
model = Profile
def get(self, request, *args, **kwargs):
#lots of irrelevant code#
if request.user.is_authenticated():
pass
else:
login_form = django_login(request, template_name='accounts/login.html', authentication_form=LoginForm).render()
#lots of irrelevant code#
context.update({
#lots of irrelevant code#
'login_form': login_form,
})
Do I even need to update context for login_form? Anyways, using it like this I get the same VariableDoesNotExist at /profiles/whateverurl/: Failed lookup for key [form].
When I replace {% crispy form form.helper %} with {% crispy login_form login_form.helper %} I get VariableDoesNotExist at /profiles/whateverurl/: Failed lookup for key [helper] instead.
I also tried to clone the working view into profiles/views.py and it does work, but only independently. If I include the new login view's template into ProfileView's template, it returns the error shown above.
Django's login view includes the login form in the template context as form. Therefore you should use:
{% crispy form form.helper %}
response = django_login(request, template_name='accounts/login.html', authentication_form=LoginForm)
is a view, and the form variable in its context is named form:
context = {
'form': form,
...
}
Thus you have to use
{% crispy form form.helper %}

Categories

Resources