Django Redirect treating view as a URL - django

For some reason, Redirect thinks my call to a view 'clients.views.teacher_profile' is a URL, putting it directly in the address bar as shown:
Page Not Found Screenshot
How do I link it to the view and not treat it as a URL?
Note: I have altered some settings to accommodate django-allauth.
My code:
#views.py
def teacher_profile(request, username):
user = get_object_or_404(User, username=username)
context = {
'user':user,
'teacher':user.teacher,
}
return render(request, 'clients/teacher_profile.html', context)
def edit_profile(request):
teacher = get_object_or_404(Teacher, user=request.user)
if request.method == 'POST':
form = TeacherForm(request.POST, instance=teacher)
if form.is_valid():
teacher = form.save(commit=False)
teacher.user = request.user
teacher.save()
return redirect('clients.views.teacher_profile', username=request.user.username)
else:
form = TeacherForm(instance=teacher)
return render(request, 'clients/edit_profile.html', {'form':form})
#urls.py
urlpatterns = [
url(r'^list/$', views.teacher_list, name='teacher_list'),
url(r'^(?P<username>[\w.#+-]+)/$', views.teacher_profile, name='teacher_profile'),
url(r'^accounts/settings/$', views.edit_profile, name='edit_profile'),
]

Don't use the view's module path in the call to redirect; use the name which you explicitly defined in the url pattern.
return redirect('teacher_profile', username=request.user.username)

Related

Django - changing ID field

So I understand it's not good practice to use the keyword - ID. So, I tried changing the id below to cid. However, when I do this I get: testing() got an unexpected keyword argument 'id'. If I change it back from cid to ID. Everything works just fine. What am I doing wrong?
def testing(request, cid):
"""Testing sheet for controls"""
if request.method == "GET":
testing_sheet = IsoControls.objects.get(pk=cid)
form = forms.ControlTesting(instance=testing_sheet)
return render(request, 'controls_app/testing_sheet.html', {'form':form})
else:
testing_sheet = IsoControls.objects.get(pk=cid)
form = forms.ControlTesting(request.POST, instance=testing_sheet)
if form.is_valid():
form.save()
return render(request, 'controls_app/testing_sheet.html', {'form':form})
Updating based on comments.
My URL is
urlpatterns = [
path('', views.home, name='home'),
path('<int:id>', views.testing, name='testing')
]
In my html
<td>
<i class="fas fa-edit"></i>
</td>
def testing(request, pk):
"""Testing sheet for controls"""
testing_sheet = IsoControls.objects.get(id=pk)
form = forms.ControlTesting(instance=testing_sheet)
if request.method=='POST':
form = forms.ControlTesting(request.POST, instance=testing_sheet)
if form.is_valid():
form.save()
return redirect('../your_given_path_name')
return render(request, 'controls_app/testing_sheet.html', {'form':form})
Ok - so this was a silly mistake. I changed it CID in my views but i also needed to change the URL partern to CID.
URL:
urlpatterns = [
path('', views.home, name='home'),
path('<int:cid>', views.testing, name='testing')
]
Views
def testing(request, cid):
"""Testing sheet for controls"""
if request.method == "GET":
testing_sheet = IsoControls.objects.get(pk=cid)
form = forms.ControlTesting(instance=testing_sheet)
return render(request, 'controls_app/testing_sheet.html', {'form':form})
else:
testing_sheet = IsoControls.objects.get(pk=cid)
form = forms.ControlTesting(request.POST, instance=testing_sheet)
if form.is_valid():
form.save()
return render(request, 'controls_app/testing_sheet.html', {'form':form})

Can't work modal form with method POST in Django

Thats my first project in Django. I want to make table and add items with modal form. I use Mysql database. items which addes manually from phpmyadmin already exist on table but when i try add from modal form it cant added.
views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Client
def viewpost(request):
post_list = Client.objects.all()
context = {
'posts': post_list
}
return render(request, 'mysite/viewtable.html', context)
def add_client(request):
if request.method == 'POST':
post = Client()
post.name = request.POST.get('name')
post.surname = request.POST.get('surname')
post.address = request.POST.get('address')
post.gender = request.POST.get('gender')
post.age = request.POST.get('age')
post.save()
return render(request, 'mysite/viewtable.html')
else:
return render(request, 'mysite/viewtable.html')
url.py:
from django.urls import path
from . import views
urlpatterns = {
path('viewtable/', views.viewpost, name='viewpost'),
path('viewtable/#add_data_Modal', views.add_client, name='add_client'),
}
Before the table and modal form didnt work together. If table worked then modal form didnt add to database or conversely. Now the're work together: Modal form add to database then table show data on page. But when i refresh page data add to databse twice.
views.py:
def viewpost(request):
post_list = Persona.objects.all()
context = {
'posts': post_list
}
if request.method == 'POST':
if request.POST.get('name') and request.POST.get('surname') and request.POST.get('address'):
post = Client()
post.name = request.POST.get('name')
post.surname = request.POST.get('surname')
post.address = request.POST.get('address')
post.age = request.POST.get('age')
post.save()
return render(request, 'mysite/viewtable.html', context)
else:
return render(request, 'mysite/viewtable.html')
Thats SOLVED. Here's view
def viewpost(request):
post_list = Persona.objects.all()
if request.method == 'POST':
if request.POST.get('name') and request.POST.get('surname') and
request.POST.get('address'):
post = Persona()
post.name = request.POST.get('name')
post.surname = request.POST.get('surname')
post.address = request.POST.get('address')
post.age = request.POST.get('age')
post.save()
return HttpResponseRedirect('/viewtable')
else:
return render(request, 'mysite/viewtabel.html', {'posts': post_list}

Django - Having two views in same url

I am making a website in django and in my homepage I want to show the list of my recent blog post and a few blocks below I want to make a simple contact form. The blog and the contact form separately are working fine. But I want to include them in the same page(obviously in the same url).
The views.py is:
from .forms import NameForm
def get_name(request):
if request.method == 'POST':
form = NameForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
form = NameForm()
return render(request, 'personal/index.html', {'form': form})
If you want to look at the forms.py then :
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
The urlpattern in urls.py of my homepage is:
urlpatterns = [
url(r'^$', ListView.as_view(
queryset=Post.objects.all().order_by("-date")[:2],
template_name="personal/index.html")),
url(r'^$', views.get_name, name='contact'),
]
With this urlpatter the list of blog post shows up perfectly but the contact form doesn't show up. But with the below urlpattern contact form shows up but blog posts doesn't show up.
urlpatterns = [
url(r'^$', views.get_name, name='contact'),
url(r'^$', ListView.as_view(
queryset=Post.objects.all().order_by("-date")[:2],
template_name="personal/index.html")),
]
I want to make both of these contents show up in the same page. Please help me. If you need any more information then do tell.
It is not possible to have multiple views for the same URL. You can only have one view for each URL.
In this case, the easiest fix is to update your get_name view so that it includes the posts in the template context.
def get_name(request):
if request.method == 'POST':
form = NameForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
form = NameForm()
post_list = Post.objects.all().order_by("-date")[:2]
return render(request, 'personal/index.html', {'form': form, 'post_list': post_list})
Then remove the url pattern that uses ListView so that get_name handles the requests.
While you cannot do that directly, you could consider your function in views.py to handle the request in a way that when it gets a post request from one model then it initialises the form for the respective model only. For this to happen you will need to assign a name to your button. See below code -
def SignUpLogin(request):
message = ""
Login_message = ""
print(request.POST)
if request.method == 'POST':
if request.POST.get('UserForgotPassword') == 'Sign Up':
form_SignUP_Login = LoginForm()
print("POST request received")
print(request.POST)
form_SignUP=SignUpForm(request.POST)
print(form_SignUP)
if form_SignUP.is_valid():
if request.POST["Password"] != request.POST["Confirm_Password"]:
message = "* Passwords do not match"
#raise forms.ValidationError(('Passwords do not match'), code="PasswordNotMatched")
else:
try:
user = User.objects.get(username=request.POST["Username"])
context= {'form': form_SignUP, 'error':'* Username already taken. Please try different username.'}
return render(request, 'User/SignUp.html', context)
except User.DoesNotExist:
user = User.objects.create_user(request.POST["Username"], request.POST["Email"], request.POST["Password"])
user.first_name = request.POST["First_Name"]
user.last_name = request.POST["Last_Name"]
user.save()
form_SignUP = SignUpModel(Username = request.POST["Username"], First_Name = request.POST["First_Name"], Last_Name = request.POST["Last_Name"], Email = request.POST["Email"], Company_Name = request.POST["Company_Name"], Address = request.POST["Address"], Password = make_password(request.POST["Password"]), Confirm_Password = make_password(request.POST["Confirm_Password"]), Phone_Number = request.POST["Phone_Number"])
form_SignUP.save()
#queryset = SignUpModel.objects.get(Username = request.POST["Username"])
#queryset.Password = "pwd_removed"
#queryset.Confirm_Password = "pwd_removed"
#queryset.save()
#send_email_to_host(request.POST["First_Name"], request.POST["Family_Name"], request.POST["Number_Of_Adults"], request.POST["Number_Of_Kids"], request.POST["Email"])
return redirect(HomePage)
elif request.POST.get('UserLogin') == 'Login':
form_SignUP = SignUpForm()
form_SignUP_Login=LoginForm(request.POST)
if form_SignUP_Login.is_valid():
user = authenticate(username=request.POST["Username"], password=request.POST["Password"])
if user is not None:
print("User authenticated")
return redirect(HomePage)
else:
print("User not authenticated")
form_SignUP_Login = LoginForm()
Login_message = "Username and password combination is not correct"
elif request.POST.get('UserForgotPassword') == 'Forgot Password':
form_SignUP = SignUpForm()
form_SignUP_Login = LoginForm()
else:
form_SignUP = SignUpForm()
form_SignUP_Login = LoginForm()
return render(request, 'User/SignUp.html', {'form' : form_SignUP, "error":message,'form_login' : form_SignUP_Login, "error_login":Login_message})

Rendering data to a template and using HttpResponseRedirect

I have this form that collects data from a user. After the data has been entered I use HttpResponseRedirect
to protect from a refresh. The problem is since I am not using a database for this app,
I can't work out how to render the data the user has entered.
At the moment the data I need to be rendered is stored in cd. So how can I still redirect the user after sucessful
data entry and pass the data to another view, then render it? I can pass it to another class view, but rendering it is the problem,
as the data is passed by MathsConfig and not through urls.
Thanks, sorry I am new to Django.
code below
views.py
class MathsConfig(View):
form_class = MathsForm
initial={'operation': "Addition",
'rows': "",
"between1": "1 - 99",
"between2": "1 - 99",
"between3": None,
"between4": None,
"between5": None,
"questions": 20,
}
template_name = 'maths/maths-config.html'
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
cd = form.cleaned_data
return HttpResponseRedirect(reverse('maths:maths_success'))
return render(request, self.template_name, {'form': form})
class MathsQuestions(object):
def __init__(self):
# want to pass cd varible here and then render it.
class MathsSuccess(TemplateView):
template_name = "maths/maths-success.html"
urls.py
urlpatterns = patterns('',
url(r'^config/$', views.MathsConfig.as_view(), name='maths_config'),
url(r'^success/$', views.MathsSuccess.as_view(), name='maths_success'),
url(r'^$', views.MathsQuestions(), name='maths_display'),
)
Edit:
class MathsQuestions(Object):
def __init__(self, request):
if 'entered_form_data' in request.session.keys():
formdata = request.session['entered_form_data']
del request.session['entered_form_data']
Store it in session.
request.session['entered_form_data'] = data
And in next view:
if 'entered_form_data' in request.session.keys():
formdata = request.session['entered_form_data']
del request.session['entered_form_data']
Edit:
def someview(request):
template = 'something.html'
form = SomeForm(request.POST) if request.method == 'POST' else SomeForm()
if request.method == 'POST':
if form.is_valid():
data = form.get_cleaned_data()
request.session['entered_form_data'] = data
return HttpResponseRedirect('/someurl/')
render_to_response(template, {'form':form}, context_instance=RequestContext(request))
def someurl_view(request):
template = 'someurl.html'
render_to_response(template, {'formdata':request.session.pop('entered_form_data', None)}, context_instance=RequestContext(request))
and of course you need to create the function, that returns data from form yourself. I mean the function which i refer to as form.get_cleaned_data(). Do it whichever way you want although i suggest you return dictionary.

Django | how to append form field to the urlconf

I want to pass a form's field value to the next page (template) after user submit the page, the field could be user name, consider the following setup
def form_submit(request):
if request.method == 'POST':
form = UsersForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
try:
newUser = form.save()
return HttpResponseRedirect('/mysite/nextpage/')
except Exception, ex:
return HttpResponse("Error %s" % str(ex))
else:
return HttpResponse('Error')
"nextpage" is the template that renders after user submit the form, so I want to know how to append the form's field (user name) to the url and get that value from the view in order to pass it to the next page..
thanks.
Change redirect in your controller to include the user name (I guessed at the field name):
def form_submit(request):
if request.method == 'POST':
form = UsersForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
try:
newUser = form.save()
return HttpResponseRedirect('/mysite/nextpage/{0}/'.format(newUser.UserName)
except Exception, ex:
return HttpResponse("Ane apoi %s" % str(ex))
else:
return HttpResponse('Error')
Then you will need a new controller:
def user_redirected_here(request, username):
#do something
And finally add something like this to your urls.py to route to the new view:
urlpatterns = patterns('',
(r"^nextpage/.+$", user_redirected_here),
)