Password Confirmation error not displayed in django forms - django

I tried to compare password and confirmpassword. If i enter different password it does not raise error and redirects to loginpage.
models.py
class reg1(models.Model):
name=models.CharField(max_length=100)
city=models.CharField(max_length=100)
email=models.CharField(max_length=100)
username=models.CharField(max_length=100)
password=models.CharField(max_length=100)
cpassword=models.CharField(max_length=100)
class Meta:
db_table='reg1'
forms.py
class regform(forms.Form):
name = forms.CharField(max_length=100)
city = forms.CharField(max_length=100)
email = forms.CharField(max_length=100)
username = forms.CharField(max_length=100)
password = forms.CharField(max_length=100)
cpassword=forms.CharField(max_length=100)
def clean_password(self):
if self.data['password'] != self.data['cpassword']:
raise forms.Error('Passwords are not the same')
return self.data['password']
views.py
if myregform.is_valid():
name1 = myregform.cleaned_data['name']
city1 = myregform.cleaned_data['city']
email = myregform.cleaned_data['email']
username1 = myregform.cleaned_data['username']
password1 = myregform.cleaned_data['password']
password2=myregform.cleaned_data['cpassword']
a=reg1(name=name1,city=city1,email=email,
username=username1,password=password1,cpassword=password2)
a.save()
I expect the output as i enter a different password it will show password not matching error
I am using pycharm software and django framework with sqlite3 database.

Use a ModelForm to save yourself a bunch of typing.
You need to use clean() to validate data that relates to other fields.
You need to raise ValidationErrors.
class reg1(models.Model):
name = models.CharField(max_length=100)
city = models.CharField(max_length=100)
email = models.CharField(max_length=100)
username = models.CharField(max_length=100)
password = models.CharField(max_length=100)
cpassword = models.CharField(max_length=100)
class Meta:
db_table = "reg1"
class regform(forms.ModelForm):
class Meta:
model = reg1
exclude = ()
def clean(self, cleaned_data):
if cleaned_data["password"] != cleaned_data["cpassword"]:
raise forms.ValidationError("Passwords are not the same")
return cleaned_data
# ...
if myregform.is_valid():
a = myregform.save()

Related

How to intercept and control saving a Django POST form?

When the user is required to fill his profile, he picks a city from the Google Places Autocomplete and posts the form, in the view I extract the city Id from the Google API based on the posted text (I use the same id as pk in my db) and try to extract a city from my db.
These are the models:
class City(models.Model):
#extracted from the Google API
city_id = models.CharField(primary_key=True, max_length=150)
name = models.CharField(max_length=128, blank=True)
country = models.CharField(max_length=128, blank=True)
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile', primary_key=True)
city = models.ForeignKey(City, blank=True, null=True)
prof_pic = models.ImageField(blank=True, upload_to='profile_pictures')
This is the view:
def createprofile(request):
if request.method =='POST':
user = User.objects.get(username=request.user.username)
user_form = UserForm(data=request.POST, instance=user)
profile_form = UserProfileForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.save()
profile = profile_form.save(commit=False)
profile.user = user
#brings back the city search result as text
searched_city = request.POST['city']
#brings back city ID from the Google API
searched_city_id = population_script.get_city_json(searched_city.replace(" ", ""))['results'][0]['id']
#If it's a valid city
if searched_city_id != -1:
city = City.objects.get(city_id = searched_city_id)
profile.city = city#this is what I want to happen!
else:
return HttpResponse("There's no such city, please try a different query.")
if 'prof_pic' in request.FILES:#now save the profile pic
profile.prof_pic = request.FILES['prof_pic']
print("PROF PIC IS: " + profile.prof_pic.url)
else:
profile.prof_pic = 'images/anon.png'
profile.save()
if 'next' in request.GET:
return redirect(request.GET['next'])
else:
print (user_form.errors, profile_form.errors)
else:
user_form = UserForm()
profile_form = UserProfileForm()
return render(request,
'excurj/createprofile.html', {'user_form':user_form, 'profile_form':profile_form})
However, I keep receiving an error that what's been posted is just text while the city needs to be a City object. I can save the profile pic ok though.
Cannot assign "'Dubai - United Arab Emirates'": "UserProfile.city"
must be a "City" instance.
edit: these are the forms:
class UserForm(forms.ModelForm):
first_name = forms.CharField(
label = "First Name:",
max_length = 80,
required = True
)
last_name = forms.CharField(
label = "Last Name:",
max_length = 80,
required = True,
)
class Meta:
model = User
fields = ('first_name', 'last_name')
class UserProfileForm(forms.ModelForm):
city = forms.CharField(
label = "Your Current City:",
max_length = 200,
required = True,
)
class Meta:
model = UserProfile
fields = ('city','prof_pic', 'dob', 'sex', 'education', 'career', 'about_you',
'music_movies_books', )
Please provide a related_name to the city field in the UserProfile.
I worked around this by creating a new UserProfile field called city_search_text which saves the searched text thus it of course does not return any error. I then receive it in the POST request and comfortable pull the proper city in the view.
I handled a similar issue by overriding my forms' clean method. Something like the following will work:
def clean(self):
# fix city problem
if self.cleaned_data.get("city") is not None:
self.cleaned_data['city'] = City.objects.get(id=self.cleaned_data.get("city"))
return self.cleaned_data

BaseInlineFormSet clean method in admin false trigger?

I am trying to update a field in Admin but it raises Validation Error from clean method which I have defined as follows in forms.py:
class BasePhoneFormSet(BaseInlineFormSet):
def clean(self):
super(BasePhoneFormSet, self).clean()
if any(self.errors):
return
phone_numbers = []
for form in self.forms:
if form.cleaned_data.get('number') in phone_numbers:
raise forms.ValidationError(
'Duplicate Entry')
phone_numbers.append(form.cleaned_data.get('number'))
PhoneFormSet = inlineformset_factory(
Post,
Phone,
formset=BasePhoneFormSet,
form=PostForm,
fields = ('number',),
can_delete=False, # admin still shows delete next to the phone number
extra=0,
validate_min=True,
min_num=1,
)
This code works in the views , but in the admin, I can't update or add any phone number since it raises the same ValidationError for duplicate entry.
here is my models.py
class Post(TimeStampedModel, models.Model):
unique_id = models.CharField(max_length=6, unique=True)
user = models.ForeignKey(User, related_name='posts')
city = models.ForeignKey(City, related_name='posts')
class Phone(TimeStampedModel, models.Model):
number = models.CharField(
validators=[phone_regex], max_length=15)
post = models.ForeignKey(Post)
And this is admin.py
class PhoneInline(admin.StackedInline):
model = Phone
formset = PhoneFormSet
class PostAdmin(admin.ModelAdmin):
inlines = [
PhoneInline,
]
I looked into BaseInlineFormSet in models.forms but I got confused more.
class PhoneInline(admin.StackedInline):
model = Phone
formset = BasePhoneFormSet
fields = ('number',)
can_delete = False
extra = 0
min_num = 1

Why RelatedObjectDoesNotExist comes even after successful migration in pythonanywhere?

I know similar question asked, but in my case am getting RelatedObjectDoesNotExist after deployment to pythonanywhere.com.
"RelatedObjectDoesNotExist: User has no eisfiles."
However same codes works fine in local machine.
Model.py
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
class gwDashboard(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
htmlname = models.CharField(max_length=100)
def __str__(self): # __unicode__ on Python 2
return self.htmlname
class userInformation(models.Model):
user = models.ForeignKey(User)
DbName = models.CharField(max_length=200)
DbTable = models.CharField(max_length=200)
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(max_length=100)
class eisfiles(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
htmlname = models.CharField(max_length=100)
meterId = models.CharField(max_length=100)
esiid = models.CharField(max_length=100)
metermultiplier = models.CharField(max_length=100)
DbName = models.CharField(max_length=100,default='800WILCREST')
DbTable = models.CharField(max_length=100)
def __str__(self):
return self.htmlname
def __str__(self):
return self.DbName
class Member(models.Model):
ID = models.AutoField(primary_key=True)
FIRST_NAME = models.CharField('First name', max_length=50)
LAST_NAME = models.CharField('Last name', max_length=50)
# Using multi table inheritance - automaticly creates one to one field
class MemberDetail(Member):
DATE_OF_BIRTH = models.DateField('Date of birth')
EMAIL = models.EmailField('E-mail')
PHONE = models.CharField('Phone', max_length=15)
Views.py
def home(request):
userName = request.user
u = User.objects.get(username=userName);
DbName=u.eisfiles //THIS LINE OF CODE THROWS ERROR
try:
DbName=u.eisfiles //THIS LINE OF CODE THROWS ERROR
DbName=u.eisfiles.DbName
direct=''
return render_to_response(
'registration/result.html',
{ 'kWhHeatMap': kWhHeatMap, 'temHeatMap':temHeatMap,"histKwhChart":histKwhChart,'officeBuilding':officeBuilding},
)
except User.eisfiles.RelatedObjectDoesNotExist:
pass
return render_to_response(
'registration/result.html',
{ 'kWhHeatMap': "", 'temHeatMap':"","histKwhChart":"",'officeBuilding':""},
)
# except User.AttributeError:
# return HttpResponse('something went wrong!! try again')
finally:
pass
You may want to check if the user you're attempting to retrieve actually exists.
userName = request.user # ??? This is the user object not the username
u = User.objects.get(username=userName)
There appears to be a problem with your query.Try this instead:
user = request.user
u = User.objects.get(id=user.id)
DbName = u.eisfiles.DbName

Django 1.5 Custom User Model unknown column

I am using Django 1.5s Custom User Model. I want to let a user type their username in - and be logged in. NO PASSWORD (for testing anyway). My User Model doesnt have a password. But when i try to login to admin I get the following error:
OperationalError(1054, "Unknown column 'hrms.password' in 'field list'"
It seems to be trying to execute this query in the authenticate() method.
SELECT `myusers`.`password`, `myusers`.`last_login`, `myusers`.`id`, `myusers`.`user`, `myusers`.`name`, `myusers`.`firstname`, `myusers`.`lastname`, `myusers`.`organisation`, `myusers`.`unit`, `myusers`.`grade`, `myusers`.`email`, `myusers`.`position`, `myusers`.`manager` FROM `myusers` WHERE `myusers`.`user` = 'warrenm' "
I do not have the fields password, last_login - I dont know why its trying to get them.
Below is my code.
My Backend (auth.py)
from epmds.application.models import AuthUser
class MyBackend(object):
def get_user(self, user_id):
# get a user from the user_id
try:
return AuthUser.objects.get(pk=user_id)
except AuthUser.DoesNotExist:
return None
def authenticate(self, username=None, password=None):
# check the username/password and return a user
user = AuthUser.objects.get(user=username)
return user
MY Model
class AuthUser(AbstractBaseUser):
id = models.CharField(primary_key=True, max_length=15)
user = models.CharField('username', max_length=20, unique=True)
name = models.CharField(max_length=100)
firstname = models.CharField(max_length=100)
lastname = models.CharField(max_length=100)
organisation = models.CharField(max_length=100)
email = models.CharField(max_length=50, blank=True, null=True)
USERNAME_FIELD = 'user'
def get_full_name(self):
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
return self.first_name
class Meta:
ordering = ('lastname', 'firstname')
managed = False
db_table = 'myusers'
password is part of AbstractBaseUser so it should be added in your AuthUser model as well in table.
As you have managed=False for this model, you need to add that explicitly.

Error saving forms to two different tables

This is my form , when i save it , it saves only to the User model but not the Client model in the database , i must be missing something simple but i cant figure it out. The following is the Form and the Client model
class RegisterForm(UserCreationForm):
email = forms.EmailField(label="Email")
fullname = forms.CharField(label="Full name")
type_choice= ( ('Customer','Customer'),('Supplier','Supplier'), )
type=forms.ChoiceField(choices=type_choice)
gender_choice=( ('Male','Male'), ('Female','Female'), )
gender=forms.ChoiceField(choices=gender_choice)
address=forms.CharField(label="Address",initial="Nothing")
phone_number=forms.IntegerField()
class Meta:
model= User
fields = ("username","fullname","email","type","gender","address","phone_number")
def save(self, commit=True):
user = super(RegisterForm, self).save(commit=False)
first_name, last_name = self.cleaned_data["fullname"].split()
user.first_name = first_name
user.last_name = last_name
user.email = self.cleaned_data["email"]
user.type=self.cleaned_data["type"]
user.gender=self.cleaned_data["gender"]
user.address=self.cleaned_data["address"]
user.phone_number=self.cleaned_data["phone_number"]
client= Client(Client_ID=3,Client_FirstName=first_name,Client_PhoneNumber=user.phone_number)
if commit:
user.save()
client.save()
return user,client
This is the Client model
class Client(models.Model):
Client_ID= models.IntegerField(primary_key=True)
Client_FirstName=models.CharField(max_length=30)
Client_LastName=models.CharField(max_length=30)
Client_Gender=models.CharField(max_length=30)
Client_PhoneNumber=models.IntegerField()
Client_Address=models.CharField(max_length=100)
Client_CreditRating=models.FloatField()
edit : I am following this example to insert a new entry into the table