I'm working my way through Django and I'm creating an app that will allow users to use an ID number to sign-in to a system. So I have two views, one for users to log-in, and the other to sign-up. The former view works just fine, I can get it to display the information the user has submitted. However I can't get the second view to display the POST data to the user:
from .forms import NameForm, IdForm
from django.shortcuts import render
from django.http import HttpResponse
def sign_in(request):
if request.method == "POST":
#here will construct the form with the POST data
form = NameForm(request.POST)
#the next part is to check that the information submitted is valid
if form.is_valid():
post = form.save()
post.save()
return HttpResponse(post)
else:
return HttpResponse("Form is invalid")
else:
form = NameForm()
return render(request, 'checkin/base.html', {'form': form})
def sign_up(request):
if request.method == "POST":
form = IdForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
return HttpResponse(post)
else:
return HttpResponse('Form is invalid')
else:
form = IdForm()
return render(request, 'checkin/base.html', {'form': form})
Basically I want to make the response to be "thank you, your ID number is: post".
Here is the class for my model:
from __future__ import unicode_literals
from django.db import models
from django import forms
from django.forms import ModelForm
# Create your models here.
class Question(models.Model):
question_text = models.CharField("What is your ID?", max_length=200)
id_text = models.CharField("Enter a new identification
number",max_length=200, null=True)
def __str__(self):
return self.question_text
And here are the form classes for both views:
from django.forms import ModelForm
from .models import Question
#put the form here
class NameForm(ModelForm):
class Meta:
model = Question
fields = ['question_text']
class IdForm(ModelForm):
class Meta:
model = Question
fields = ['id_text']
It's not generally acceptable to display the POST data as the respnose to the user. That's not HTML, merely a dictionary which the average user will not understand. The standard way of using forms in Django (and indeed almost any web framework) is to display the form validation errors to the user so that he may rectify it.
The right way
def sign_up(request):
if request.method == "POST":
form = IdForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
return HttpResponseRedirect('/succes_url')
else:
form = IdForm()
return render(request, 'checkin/base.html', {'form': form})
The problem is in line return HttpResponse(post),You are passing a whole form into HttpResponse,but as you mentioned,you just need id_text field of the IdForm.
So the updated code should be :
def sign_up(request):
if request.method == "POST":
form = IdForm(request.POST)
if form.is_valid():
post = form.save()
post.save()
id = post.id_text
return HttpResponse('thank you, your ID number is: '+id)
else:
return HttpResponse('Form is invalid')
else:
form = IdForm()
return render(request, 'checkin/base.html', {'form': form})
Related
Trying to create Signup Page and store the details of user in User model but the data is not getting saved.I have imported the User model in forms.py.Below is the code of forms.py and view which is created.
Views.py
from .forms import SignUpForm,LoginForm,PostForm
def user_signup(request):
if request.method=="POST":
form = SignUpForm(request.POST)
if form.is_valid():
un=form.cleaned_data['username']
fn=form.cleaned_data['first_name']
ln=form.cleaned_data['last_name']
em=form.cleaned_data['email']
var=User(username=un,first_name=fn,last_name=ln,email=en)
var.save()
form = SignUpForm()
else:
form= SignUpForm()
return render(request,'Blog/signup.html',{'form':form})
forms.py
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
password1=forms.CharField(label='Password',widget=forms.PasswordInput(attrs={'class':'form-control'}))
password2=forms.CharField(label='Password Again',widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model = User
fields=['username','first_name','last_name','email']
labels={
'first_name':'First Name',
'last_name':'Last Name',
'email':'Email'
}
widgets={
'username':forms.TextInput(attrs={'class':'form-control'}),
'first_name':forms.TextInput(attrs={'class':'form-control'}),
'last_name':forms.TextInput(attrs={'class':'form-control'}),
'email':forms.EmailInput(attrs={'class':'form-control'})
}
If you are using save for the first time, you might have to use force_insert=True:
if form.is_valid():
un=form.cleaned_data['username']
fn=form.cleaned_data['first_name']
ln=form.cleaned_data['last_name']
em=form.cleaned_data['email']
var=User(username=un,first_name=fn,last_name=ln,email=en)
var.save(force_insert=True)
form = SignUpForm()
Or,
Directly save from the form:
if form.is_valid():
form.save()
un=form.cleaned_data['username']
fn=form.cleaned_data['first_name']
ln=form.cleaned_data['last_name']
em=form.cleaned_data['email']
form = SignUpForm()
Or,
Use create() which is specifically used to insert in data:
if form.is_valid():
un=form.cleaned_data['username']
fn=form.cleaned_data['first_name']
ln=form.cleaned_data['last_name']
em=form.cleaned_data['email']
User.objects.create(username=un,first_name=fn,last_name=ln,email=en)
form = SignUpForm()
I am building a web-app where people can write projects. The projects are stored in a model and I want to use the user as the foreign key so I can show the user their projects on a webpage. Instances are entered through a form.
The code always assigns the default value (1) and and not the user. Can any of you see what's causing this bug?
Here is the code for the creation of the model in models.py:
class PersonalProject(models.Model):
user = models.ForeignKey(User, default=1, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
description = models.TextField()
code = models.TextField()
def __str__(self):
return self.title
Heres the code for the form view to create the project in views.py:
def newproject(request):
if User is None:
messages.error(request, "Must be signed in")
return redirect('main:dashboard')
if request.method == "POST":
form = NewProjectForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('main:dashboard')
else:
messages.error(request, "Error")
else:
form = NewProjectForm()
return render(request,
"main/newproject.html",
{"form":form})
Heres the code for the homepage view in views.py:
def dashboard(request):
messages.info(request, request.user.username)
return render(request=request,
template_name="main/dashboard.html",
context={"structuredprojects": StructuredProject.objects.all(), "personalprojects": PersonalProject.objects.filter(user__username=request.user.username)})
I really hope you can help - I've been stuck on this for a while
You can set the user of the instance wrapped in the form to request.user:
from django.contrib.auth.decorators import login_required
#login_required
def newproject(request):
if request.method == "POST":
form = NewProjectForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('main:dashboard')
else:
messages.error(request, "Error")
else:
form = NewProjectForm()
return render(request,
"main/newproject.html",
{"form":form})
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].
In my Django project, I have to take the input from forms and pass it as an argument for a function that is in views.py. How do I do it?
My views.py code
from django.shortcuts import render,render_to_response
from django.http import Http404, HttpResponse, HttpResponseRedirect
from search_engine import query
from .forms import SearchForm
def query_input(request):
if request.method == "POST":
form = SearchForm(request.POST)
else:
form = SearchForm()
return render(request, 'search.html', {'form': form})
def search_results(request):
search_results = query.results(# text input from forms)
a = "<br /><br />".join(word for word in search_results)
return HttpResponse(a)
My forms.py code
from django import forms
class SearchForm(forms.Form):
your_query = forms.CharField(max_length=100)
After you checked that the request method is a POST you can validate the form and then access its attributes like this
In views.py:
if request.method = "POST":
form = SearchForm(request.POST)
if form.is_valid():
search_text = form.cleaned_data['search_text']
# code from search_results function to return HTTP Response
Check out the documentation on forms and view here for more information.
The problem that I face, is that I do not know how to assign a group to a user directly from a formal registration of a template (application) in Django. My user registration view is this:
def UserRegister(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('login')
else:
form = UserCreationForm()
return render(request, 'register/user_register.html', {'form': form})
POSTDATA: to assign roles, I use django-role-permissions. I do not want to register a group, I just want to include it with the user who registers without having to do in the Django panel.
Typically you would pull in the group model from django. Then query the model for the group you would like to add the user. Here is how to below.
from django.contrib.auth.models import Group
def UserRegister(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
group = Group.objects.get(name='group_name')
user.groups.add(group)
return redirect('login')
else:
form = UserCreationForm()
return render(request, 'register/user_register.html', {'form': form})
I have a simple user registration form (in forms.py):
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput
validators=[MinLengthValidator(6)])
password_repeat = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'password','password_repeat']
If someone tries to enter something and the validation fails I want the same form to be rendered again but all fields should be cleared. At the moment my view looks like this (in views.py):
def signup(request):
form = UserForm(request.POST or None)
if form.is_valid():
user = form.save(commit=False)
username = form.cleaned_data['username']
password = form.cleaned_data['password']
password_repeat = form.cleaned_data['password-repeat']
user.set_password(password)
user.save()
user = auth.authenticate(username=username, password=password)
if user is not None and user.is_active:
auth.login(request, user)
return redirect('/')
return render(request, 'signup.html', {'form': form})
The problem is that the form.fields['username'] field still contains the username that was entered and is thus passed to render.
I've been searching for a solution a while now but can't find it. My guess is that the solution has something to do with the clean() method that I don't seem to get.
This is an odd thing to want to do - it is the opposite of the question people normally ask, as most people want to preserve the fields and show the errors.
However, if you really want to clear the form, you should just instantiate a new one.
if form.is_valid():
...
else:
form = UserForm()
return render(request, 'signup.html', {'form': form})
To always clear a particular form field while preserving all form validation errors, you can create a custom input widget that always "forgets" its old value. For example:
from django import forms
class NonstickyTextInput(forms.TextInput):
'''Custom text input widget that's "non-sticky"
(i.e. does not remember submitted values).
'''
def get_context(self, name, value, attrs):
value = None # Clear the submitted value.
return super().get_context(name, value, attrs)
class MyForm(forms.Form):
username = forms.CharField(widget=NonstickyTextInput())
# ...
Reference: django.forms.Widget.get_context
Behavior
Suppose we are using MyForm in such a view:
from django.shortcuts import render, redirect
from myapp.forms import MyForm
def myview(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
# Do something with the submitted values...
return redirect('home_page')
else:
form = MyForm()
return render(request, 'myapp/myview.html', {'form': form})
When the form encounters any validation error and the form is re-displayed, all the usual validation error messages will be shown on the form, but the displayed username form field will be blank.