I am having an issue with my forms, I've been trying to upload an image when a user registers but it does not submit because an error message is sent which says "This field is required". I'm not too sure where the issue is but I have tried to do this "a_form=InformationForm(request.POST, request.FILES)". But I still got the error message("This field is required") upon registration of the user, even though I have selected the image to be uploaded with the user when registering. I would like to know if a solution could be proffered. The image and code snippet show the issue too. Thanks
FORMS
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Information
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': 'Email'}))
username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Username'}))
first_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'First name'}))
last_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Last name'}))
password1 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
password2 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Confirm'}))
class Meta:
model = User
fields = ['username','first_name','last_name', 'email', 'password1', 'password2']
class InformationForm(forms.ModelForm):
#sex=forms.ChoiceField(choices=CHOICES)
department = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Department'}))
majors = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Majors'}))
nationality = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Nationality'}))
date_of_birth = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'yyyy/mm/dd'}))
passport_number = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Passport number'}))
phone_number = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Phone number'}))
student_passport = forms.ImageField()
class Meta:
model=Information
fields=['department','majors','degree','years','nationality','date_of_birth','passport_number','phone_number','sex','student_passport']
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['email']
class InformationUpdateForm(forms.ModelForm):
class Meta:
model=Information
fields=['phone_number']
VIEWS
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm,UserUpdateForm ,InformationUpdateForm,InformationForm
def home(request):
return render(request, 'student/home.html')
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
a_form=InformationForm(request.POST, request.FILES)
if form.is_valid() and a_form.is_valid():
user = form.save()
information = a_form.save(commit=False)
information.user = user
information.save()
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
else:
form = UserRegisterForm()
a_form = InformationForm()
context={'form':form,'a_form':a_form }#,'a_form':a_form
return render(request, 'student/register.html', context)
#login_required
def profile(request):
return render(request, 'student/profile.html')
#login_required
def passport(request):
return render(request,'student/passport.html')
#login_required
def profile_update(request):
if request.method == 'POST':
u_form=UserUpdateForm(request.POST,instance=request.user)
i_form=InformationUpdateForm(request.POST,request.FILES,instance=request.user.information)
if u_form.is_valid() and i_form.is_valid():
u_form.save()
i_form.save()
messages.success(request, f'Your account has been updated!')
return redirect('profile')
else:
u_form=UserUpdateForm(instance=request.user)
i_form=InformationUpdateForm(instance=request.user.information)
context={'u_form': u_form,
'i_form':i_form}
return render(request, 'student/profile_update.html',context)
REGISTER.HTML
{% extends "student/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group" enctype="multipart/form-data">
<legend class="border-bottom mb-4">Join Today</legend>
{{ form|crispy }}
{{ a_form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit" value="submit">Sign Up</button>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted">
Already Have An Account? <a class="ml-2" href="{% url 'login' %}">Sign In</a>
</small>
</div>
</div>
{% endblock content %}
Have you added enctype="multipart/form-data" in form tag?
<form action="" method="post" enctype="multipart/form-data">
{{form}} //your form stuff
</form>
you applied enctype="multipart/form-data" to <fieldset> please add in <form> tag
Related
I've two forms rendering in a single function based view, it is diplaying validation errors of only one form when i click the signup button but when i click the login button it just reload my page
and doesn't showing any validation error
views.py
def register(request):
form = RegisterForm()
form_b = LogInForm()
if request.POST.get('submit') == 'sign_up':
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
elif request.POST.get('submit') == 'log_in':
form1 = LogInForm(request=request, data=request.POST)
if form1.is_valid():
uname = form1.cleaned_data['username']
upass = form1.cleaned_data['password']
user = authenticate(username=uname, password=upass)
if user is not None:
login(request, user)
return redirect('/shop/')
else:
form = RegisterForm()
form_b = LogInForm()
return render(request, 'reg.html', {'form': form, 'form1': form_b})
forms.py
from distutils.command.clean import clean
from xml.dom import ValidationErr
from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.models import User
class RegisterForm(UserCreationForm):
password1 = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ['username', 'email']
class LogInForm(AuthenticationForm):
username = forms.CharField(widget=forms.TextInput())
password = forms.CharField(widget=forms.PasswordInput())
reg.html
<form class="loginForm" action="" method="POST" novalidate>
{% csrf_token %}
{% for field in form %}
<p> {{field.label_tag}} {{field}} </p>
<p> {{field.errors}} </p>
{% endfor %}
<button type="submit" class="btnLogin" name='submit' value='sign_up'>Sign Up</button>
</form>
<form class="loginForm" action="" method="post" novalidate>
{% csrf_token %}
{% for field in form1 %}
<p> {{field.label_tag}} {{field}} </p>
<p> {{field.errors | striptags}} </p>
{% endfor %}
<button class="btnLogin" type="submit" name='submit' value='log_in'>Log In </button>
</form>
Try to create seperate view for both register and login.
try this way:
views.py:
def register(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid:
form.save()
username = form.cleaned_data.get('username')
# messages.success(request,f'Welcome { username }')
return HttpResponseRedirect('/users/')
else:
form = RegisterForm()
return render(request,'users/register.html',{'form':form})
And in urls.py:
path('login',auth_views.LoginView.as_view(template_name='users/login.html'),name='login'),
I am trying to find a way to let the user change his own image and I couldn't do it because I am new to Django and please if you can help me in a way that is the same as my flow of code so I don't get confused or if you can just explain Thank You,
Forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from accounts.models import UserProfile
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = (
'username',
'first_name',
'last_name',
'email',
'password1',
'password2'
)
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
class EditProfileForm(UserChangeForm):
template_name='/something/else'
class Meta:
model = User
fields = (
'email',
'first_name',
'last_name',
)
Models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfileManager(models.Manager):
def get_queryset(self):
return super(UserProfileManager, self).get_queryset().filter(city='London')
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
description = models.CharField(max_length=100, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
image = models.ImageField(upload_to='image/', blank=True)
objects = models.Manager()
london = UserProfileManager()
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
Profile.Html
{% extends 'base.html' %}
{% load static %}
{% block head %}
<title>Profile</title>
{% endblock %}
{% block content %}
<div class="container">
<br><br>
<div class="row">
<br><br>
<div class="col-4">
{% if user.userprofile.image %}
<img class="UserImage" src="{{ user.userprofile.image.url }}" height="240" width="240">
{% else %}
<img class="UserImage image" src="{% static 'defaultui.jpg' %}" height="240" width="240">
{% endif %}
</div>
<div class="col-4">
<h1>Profile</h1>
<p><b>Username:</b> {{ user }}</p>
<p><b>First name:</b> {{ user.first_name }}</p>
<p><b>Last name:</b> {{ user.last_name }}</p>
<p><b>Email:</b> {{ user.email }}</p>
<p><b>Description:</b>Description: {{ user.userprofile.description }}</p>
<p><b>Phone:</b> {{ user.userprofile.phone }}</p>
<p><b>City:</b> {{ user.userprofile.city }}</p>
<p><b>Website:</b> {{ user.userprofile.website }}</p>
</div>
</div>
<h1>Your Posts</h1>
</div>
{% endblock %}
edit profile.html
{% extends 'base.html' %}
{% block content %}
<div class="container">
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="button" class="btn btn-success" name="button">Change Password</button>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
<br>
</div>
{% endblock %}
views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.models import User
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserChangeForm, PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
from django.urls import reverse
from accounts.forms import (
RegistrationForm,
EditProfileForm
)
from products.models import Product
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserChangeForm, PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
def register(request):
if request.method =='POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
form = RegistrationForm()
args = {'form': form}
return render(request, 'accounts/reg_form.html', args)
def view_profile( request, pk=None):
product = Product()
if pk:
user = User.objects.get(pk=pk)
else:
user = request.user
args = {'user': user, 'product':product}
return render(request, 'accounts/profile.html', args)
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('view_profile')
else:
form = EditProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'accounts/edit_profile.html', args)
def change_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('view_profile')
else:
return redirect('change_password')
else:
form = PasswordChangeForm(user=request.user)
args = {'form': form}
return render(request, 'accounts/change_password.html', args)
def login(request):
if request.method == 'POST':
user = auth.authenticate(username=request.POST['username'],password=request.POST['password'])
if user is not None:
auth.login(request, user)
return redirect('home')
else:
return render(request, 'accounts/login.html',{'error':'username or password is incorrect.','user':user})
else:
return render(request, 'accounts/login.html')
def logout(request):
if request.method == 'POST':
auth.logout(request)
return redirect('home')
Try using ModelForm as form and use UserProfile to change the image, not User. Something similar to:
class UserChangeProfileForm(ModelForm):
class Meta:
model = UserProfile
fields = ['image']
Also, check and use crispy forms instead of manually declaring them.
I am setting up a website in Django, where users can see their profiles and update details (like email, password, etc) or delete own account. But updating the form is not acknowledged at all by the user. I am using the standard built-in User model.
forms.py:
class UserDetailsForm(forms.ModelForm):
password = forms.CharField(widget = forms.PasswordInput())
class Meta:
model = User
fields = ('first_name','last_name','email','password','is_active')
views.py:
#login_required
def edit_profile(request):
user = User.objects.get(username=request.user)
form = UserDetailsForm(request.POST or None,
initial={'first_name':user.first_name,
'last_name':user.last_name,
'email':user.email,
'password':user.password,
'is_active':user.is_active,})
if request.method == 'POST':
if form.is_valid():
user.save()
messages.info(request, 'This is a debug message')
return HttpResponseRedirect(reverse('account'))
context = {"form": form}
return render(request, "iFood/user-account.html", context)
user-profile.html:
...
<form method="POST" action="{% url 'account' %}" class="" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" name="" value="Edit and Save">
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li class="{{ message.tags }}">
{{ message }}
</li>
{% endfor %}
</ul>
{% endif %}
First of all you can't change a password like that. You should take the password that user entered and set it with user_obj.set_password():
Django docs: Change password
And for your form:
You doing it wrong with user.save(). There is nothing to save for user object. You should save the form using form.save().
Also request.user is the actual user object not the username.
forms.py:
class UserDetailsForm(forms.ModelForm):
password = forms.CharField(widget = forms.PasswordInput())
class Meta:
model = User
fields = ('first_name','last_name','email'','is_active')
views.py:
#login_required
def edit_profile(request):
user = request.user
form = UserDetailsForm(request.POST or None, instance=user)
if request.method == 'POST':
if form.is_valid():
# Save the changes but password
form.save()
# Change password
new_password = form.cleaned_data.get('password')
if new_password:
user.set_password(new_pass)
messages.info(request, 'This is a debug message')
return HttpResponseRedirect(reverse('account'))
context = {"form": form}
return render(request, "iFood/user-account.html", context)
I was creating a user registration system in django1.8. But when I click register button on the form, it does not redirect to the success url. I am also not sure if this is the right way to save a user information in the database. Please recommend if there is a better way to approach user registration in django.
Models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
age = models.IntegerField(blank=True)
gender_choices = (('M', 'Male'), ('F', 'Female'))
gender = models.CharField(max_length=1, choices=gender_choices, default='Male')
forms.py
from django import forms
from .models import UserProfile
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
exclude = ['user']
Views.py
from django.shortcuts import render, redirect
from django.core.urlresolvers import reverse
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .forms import UserProfileForm
# Create your views here.
def registerView(request):
if request.method == "POST":
user_form = UserCreationForm(request.POST)
user_profile_form = UserProfileForm(request.POST)
if user_form.is_valid() and user_profile_form.is_valid():
new_user = user_form.save()
new_user_profile = user_profile_form.save()
return redirect(reverse('success'))
else:
return render(request, 'register.html', {'user_form': user_form, 'user_profile_form': user_profile_form})
else:
user_form = UserCreationForm(request.POST)
user_profile_form = UserProfileForm(request.POST)
return render(request, 'register.html', {'user_form': user_form, 'user_profile_form': user_profile_form})
def successView(request):
username = User.objects.get('username')
return render(request, 'success.html', {'username': username})
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.registerView, name='register'),
url(r'^success/$', views.successView, name='success')
]
register.html
<h1> Welcome </h1>
<form method="POST" action="{% url 'success' %}">
{% csrf_token %}
{{ user_form.as_p }}
{{ user_profile_form.as_p }}
<input type="button" value="Register"/>
</form>
success.html
<h4> Yo Mr...{{ username }}</h4>
<h1>Welcome</h1>
You need to make the following changes:
<h1> Welcome </h1>
<form method="POST" action="{% url 'register' %}">
{% csrf_token %}
{{ user_form.as_p }}
{{ user_profile_form.as_p }}
<input type="submit" value="Register"/>
</form>
views.py
def crave_view(request):
if (request.method=="POST"):
form1=CraveDataForm(request.POST, request.FILES)
form2 = CraveReplyForm(request.POST, request.FILES)
print form1
print form2
if form1.is_valid() and form2.is_valid():
crave_made = form1.save(commit=False)
crave_made.person = request.user
crave_made.save()
reply = form2.save(commit=False)
reply.person=request.user
reply.crave = crave_made
reply.save()
#login(request,crave_made.username,form1.clean_password2())
messages.success(request, 'You Registered Successfully')
#return HttpResponseRedirect('/details/')
else:
print form1
print form2
messages.error(request, 'Please enter all required fields')
else:
form2 = CraveReplyForm()
form1=CraveDataForm()
return render(request, "crave/crave.html", { 'form1' : form1, 'form2' : form2 })
models.py
class crave_data(models.Model):
person = models.ForeignKey(User)
post=models.TextField(blank = True,null = True)
date= models.DateTimeField(auto_now_add=True, blank=True)
def __unicode__(self):
return self.post
class comments(models.Model):
crave=models.ForeignKey(crave_data)
reply=models.CharField(max_length=1000, blank = True,null = True)
date= models.DateTimeField(auto_now_add=True, blank=True)
def __unicode__(self):
return self.reply
forms.py
class CraveDataForm(forms.ModelForm):
class Meta:
model = crave_data
exclude=['date', 'password1', 'password2', 'username', 'person']
class CraveReplyForm(forms.ModelForm):
class Meta:
model = comments
exclude=['date', 'crave', 'password1', 'password2', 'username']
crave.html
<form class="horizontal-form" role="form" action="." method="post" style="padding: 10px;">
{% csrf_token %}
<div class="form-group" >
<div class="col-sm-10">
{{ form1.post.label_tag }}{{ form1.post }} <br /><br>
</div>
</div>
<input type="submit" class="btn btn-success" value="crave" />
</form>
<form class="horizontal-form" role="form" action="." method="post" style="padding: 10px;">
{% csrf_token %}
<div class="form-group" >
<div class="col-sm-10">
{{ form2.reply.label_tag }} {{ form2.reply }} </br> </br>
</div>
</div>
<input type="submit" class="btn btn-success" value="reply" />
</form>
i want to submit data of form one only, but the thing is happening that for form2 i.e. for comment blank object is getting created, its due to a foriegn key i given in comment class.
i dont want the blank object getting created for form2. The data should get saved for form2 after clicking on the submit button of form2. And i can not remove foreign key relationship from there also. reply should get submitted for that relative crave only. and data should get submitted independantlly.
I dont want data to be saved for both form after clicking on submit button of one form.
You shouldn't use one view function for two different actions.
You should do view for add/edit Crave objects like this:
from django.shortcuts import get_object_or_404
from django.core.exceptions import PermissionDenied
from django.contrib.auth.decorators import login_required
#login_required
def crave_edit(request, id=None):
instance = get_object_or_404(crave_data, pk=id) if id else None
if instance and instance.person != request.user:
raise PermissionDenied()
if request.method=="POST":
form=CraveDataForm(request.POST, request.FILES, instance=instance)
if form.is_valid():
crave_made = form.save(commit=False)
crave_made.person = request.user
crave_made.save()
else:
form=CraveDataForm(instance=instance)
return render(request, "crave/crave_edit.html", {'form' : form})
Once again, you shouldn't mix add/edit Crave with add comments. You can't add comment to non-exist entity:
#login_required
def crave_view(request, id):
crave = get_object_or_404(crave_data, pk=id)
if request.method=="POST":
form=CraveReplyForm(request.POST, request.FILES)
if form.is_valid():
reply = form.save(commit=False)
reply.person=request.user
reply.crave = crave
reply.save()
else:
form=CraveReplyForm()
return render(request, "crave/crave_view.html", {'crave': crave, 'form' : form})
And please note that names for models should be capitalised, without underlines - "crave_data" is bad style
You can make the foreign key field optional in Django model
Try this way,
crave=models.ForeignKey(crave_data, blank=True, null=True)
If you want submit the forms independently. then put the hidden input field in one form and separate the form logic in view based on hidden input. Like this,
if 'hidden_input' in request.POST.keys():