views.py
if pform.is_valid():
user = pform.save()
forms.py
class UserProfileForm(forms.ModelForm):
sex = forms.CharField(max_length = 20,label="I am :",widget=forms.Select(choices=SEX_CHOICES,attrs = {'class':''}),required = False)
first_name = forms.CharField(max_length = 50,widget = forms.TextInput(attrs={'placeholder':'Please enter your real name.','class':''}),required = False)
last_name = forms.CharField(max_length = 50,widget = forms.TextInput(attrs={'placeholder':'Enter last name.','class':''}),required = False)
location = forms.CharField(max_length = 50,widget = forms.TextInput(attrs={'placeholder':'Enter your current location','class':''}),required = False)
def clean_first_name(self):
first_name = self.cleaned_data['first_name']
if first_name == '':
raise forms.ValidationError("This field is required.")
return first_name
def clean_phone(self):
phone = self.cleaned_data['phone']
if phone == '':
raise forms.ValidationError("This field is required.")
return phone
def clean_last_name(self):
last_name = self.cleaned_data['last_name']
if last_name == '':
raise forms.ValidationError("This field is required.")
return last_name
def clean_profession(self):
profession = self.cleaned_data['profession']
if profession == "":
raise forms.ValidationError("Select a valid option.")
return profession
def clean_sex(self):
sex = self.cleaned_data['sex']
if sex == "":
raise forms.ValidationError("Select a valid option.")
return sex
def __init__(self,*args,**kw):
super(UserProfileForm,self).__init__(*args,**kw)
self.phone = self.instance.get_profile().phone
self.profession = self.instance.get_profile().profession
self.sex = self.instance.get_profile().sex
self.location = self.instance.get_profile().location
def save(self,*args,**kw):
self.instance.first_name = self.cleaned_data.get("first_name")
self.instance.last_name = self.cleaned_data.get("last_name")
self.instance.get_profile().sex = self.cleaned_data.get("sex")
self.instance.get_profile().location = self.cleaned_data.get("location")
self.instance.get_profile().profession = self.cleaned_data.get("profession")
self.instance.get_profile().phone = self.cleaned_data.get("phone")
self.instance.save()
return self.instance
class Meta:
model = User
fields = ('first_name','last_name','phone','sex','profession','location')
#exclude = ('email')
doubt
everything is working fine but y am i not able to save the information to the user profile , when i use the self.instance.get_profile().phone = self.cleaned_data.get('#some_field') , because when i am retrieving the data its not showing up in m form , please help , thanks in advance
If I understood you well, then you get data from the form and can't save it to the users profile. To fix this, you need do save user profile too:
def save(self,*args,**kw):
self.instance.first_name = self.cleaned_data.get("first_name")
self.instance.last_name = self.cleaned_data.get("last_name")
profile = self.instance.get_profile()
profile.sex = self.cleaned_data.get("sex")
profile.location = self.cleaned_data.get("location")
profile.profession = self.cleaned_data.get("profession")
profile.phone = self.cleaned_data.get("phone")
profile.save()
self.instance.save()
return self.instance
You shouldn't use a # when fetching the field. Do this instead:
self.cleaned_data.get('some_field')
Related
In Django, I want to build a form that collects shipping addresses from users! Then save them to database
There is views.py starts with defining a function "is_valid_form(values)"
def is_valid_form(values):
valid = True
for field in values:
if field == '':
valid = False
return valid
class EnCheckoutView(View):
def get(self, *args, **kwargs):
try:
order = Order.objects.get(user=self.request.user, ordered=False)
form = CheckoutForm()
context = {
'form': form,
'couponform': CouponForm(),
'order': order,
'DISPLAY_COUPON_FORM': True
}
shipping_address_qs = Address.objects.filter(user=self.request.user, address_type='S', default=True)
if shipping_address_qs.exists():
context.update({
'default_shipping_address': shipping_address_qs[0]
})
return render(self.request, 'en-checkout-page.html', context)
except ObjectDoesNotExist:
messages.info(self.request, 'You do not have an active order.')
return redirect('core:en-checkout')
def post(self, *args, **kwargs):
try:
order = Order.objects.get(user=self.request.user, ordered=False)
except ObjectDoesNotExist:
messages.warning(self.request, 'You do not have an active order')
return redirect('core:en-order-summary')
form = CheckoutForm(self.request.POST or None)
if form.is_valid():
use_default_shipping = form.cleaned_data.get("use_default_shipping")
if use_default_shipping:
print('Using the default shipping address')
address_qs = Address.objects.filter(user=self.request.user, default=True)
if address_qs.exists():
shipping_address = address_qs[0]
order.shipping_address = shipping_address
order.save()
else:
messages.info(self.request, 'No default shipping address available')
return redirect('core:en-checkout')
else:
print('User is entering a new shipping address')
customer_name = form.cleaned_data.get('customer_name')
phone = form.cleaned_data.get('phone')
email = form.cleaned_data.get('email')
shipping_address1 = form.cleaned_data.get('shipping_address1')
shipping_address2 = form.cleaned_data.get('shipping_address2')
en_shipping_country = form.cleaned_data.get('en_shipping_country')
shipping_zip = form.cleaned_data.get("shipping_zip")
if is_valid_form([customer_name, phone, shipping_address1]):
shipping_address = Address(
user=self.request.user,
customer_name=customer_name,
phone=phone,
email=email,
street_address=shipping_address1,
apartment_address=shipping_address2,
country=en_shipping_country,
zip=shipping_zip,
address_type='S'
)
shipping_address.save()
order.shipping_address = shipping_address
order.save()
set_default_shipping = form.cleaned_data.get('set_default_shipping')
if set_default_shipping:
shipping_address.default = True
shipping_address.save()
else:
messages.info(self.request, 'Please ***fill in the required shipping address fields')
en_payment_option = form.cleaned_data.get('en_payment_option')
if en_payment_option == 'S':
return redirect('core:en-payment', en_payment_option='Pay with credit card')
elif en_payment_option == 'P':
return redirect('core:ar-delivery', en_payment_option='Cash on delivery')
else:
messages.warning(self.request, 'Invalid payment option selected')
return redirect('core:en/checkout')
Why this form does not save the address to the database?
I could have posted forms.py, html template, and models.py, but I guess that will explain the problem.
forms.py
EN_PAYMENT_CHOICES = (
('S', 'Pay with credit card'),
('P', 'Cash on delivery')
)
class CheckoutForm(forms.Form):
customer_name = forms.CharField(max_length=100, required=True)
phone = forms.IntegerField(required=True)
email = forms.EmailField()
shipping_address1 = forms.CharField(required=True)
shipping_address2 = forms.CharField(required=False)
ar_shipping_country = CountryField(blank_label='(اختار البلد)').formfield(
required=False,
widget=CountrySelectWidget(attrs={
'class': 'custom-select d-block w-100',
}))
en_shipping_country = CountryField(blank_label='(Choose a country)').formfield(
required=False,
widget=CountrySelectWidget(attrs={
'class': 'custom-select d-block w-100',
}))
shipping_zip = forms.CharField(required=False)
set_default_shipping = forms.BooleanField(required=False)
use_default_shipping = forms.BooleanField(required=False)
payment_option = forms.ChoiceField(
widget=forms.RadioSelect, choices=PAYMENT_CHOICES)
en_payment_option = forms.ChoiceField(
widget=forms.RadioSelect, choices=EN_PAYMENT_CHOICES)
models.py
class Address(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
customer_name = models.CharField(max_length=100, null=True)
phone = models.IntegerField(null=True)
email = models.EmailField(null=True)
street_address = models.CharField(max_length=250)
apartment_address = models.CharField(max_length=250)
country = CountryField(multiple=False, null=True)
zip = models.CharField(max_length=100)
address_type = models.CharField(max_length=1, choices=ADDRESS_CHOICES)
default = models.BooleanField(default=False)
def __str__(self):
return self.user.username
class Meta:
verbose_name_plural = 'Addresses'
I have a working piece of code which runs fine.
Here's the model:
class Therapist(models.Model):
user = models.OneToOneField(User)
SEX_CHOICES = (
('M','male'),
('F','female'),
)
sex = EncryptedCharField(choices = SEX_CHOICES, blank=False, max_length=20, verbose_name = "Płeć")
company = models.ManyToManyField(Company, blank=True, verbose_name = "Firma")
subscription = models.ForeignKey(Subscription, blank=False, verbose_name = "Abonament")
uuid = models.UUIDField(primary_key=False, editable=False, default=uuid.uuid4, null=True, blank=True)
def __unicode__(self):
return '%s %s' % (self.user.first_name, self.user.last_name)
def __str__(self):
return '%s %s' % (self.user.first_name, self.user.last_name)
The form:
class MyRegistrationForm(forms.Form):
SEX_CHOICES = (
('F', 'kobieta'),
('M', 'mężczyzna'),
)
first_name = forms.CharField(label="Imię")
last_name = forms.CharField(label="Nazwisko")
user_email = forms.EmailField(label="Adres e-mail")
user_sex = forms.ChoiceField(label="Wybierz swoją płeć", choices = SEX_CHOICES)
username = forms.CharField(label="Nazwa użytkownika")
password1 = forms.CharField(label="Wpisz hasło", widget = PasswordInput())
password2 = forms.CharField(label="Powtórz hasło", widget = PasswordInput())
def clean_username(self):
username = self.cleaned_data['username']
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
# this is to verify if any user exists at all. If yes - do not allow other users to be created!
if Therapist.objects.all().exists():
raise forms.ValidationError(_(u'Jakiś użytkownik już istnieje, a Twoja wersja programu nie pozwala na tworzenie więcej niż 1 użytkownika. Wersje dla więcej niż jednego terapeuty dostępne pod kontakt#zapiszsesje.pl'), code='invalid')
else:
return username
raise forms.ValidationError(u'Użytkownik o nazwie "%s" już istnieje.' % username)
def clean_user_email(self):
email = self.cleaned_data['user_email']
try:
user = User.objects.get(email =email)
except User.DoesNotExist:
return email
raise forms.ValidationError(u'Użytkownik o takim adresie email już istnieje.')
& the view:
def myRegistrationView(request):
if request.method == 'POST':
form = MyRegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(
username = form.cleaned_data['username'],
email = form.cleaned_data['user_email'],
password = form.cleaned_data['password1'],
first_name = form.cleaned_data['first_name'],
last_name = form.cleaned_data['last_name']
)
user.save()
subscription = Subscription(
expired_on = datetime.datetime.now() + datetime.timedelta(days = 90)
)
subscription.save()
therapist = Therapist(
user = user,
sex = form.cleaned_data['user_sex'],
subscription = subscription,
)
therapist.save()
return HttpResponseRedirect(reverse('registration_gotowe'))
else:
form = MyRegistrationForm()
param = {
'form':form
}
return render(request, 'registration/registration_form.html', param)
When I package the app using a Mac and PyInstaller the app works fine until I get to that view and try to register creating a User, Subscription and Therapist. In that moment I get a
TypeError at /konto/register/
'NoneType' object is not iterable error ...
The same code works fine on Windows before and after the PyInstaller compilation to an exe file. Apart from that the app seems to work fine without any errors.
If I comment out the part of the code where the Therapist is created in the view:
therapist = Therapist(
user = user,
sex = form.cleaned_data['user_sex'],
subscription = subscription,
)
therapist.save()
the app 'works' fine - this error does not occur....
What am I missing?
I tried adding another field (pin) in forms.py and models.py
The error i got was
"FieldError at /student/signup/
Cannot resolve keyword 'pin' into field. Choices are: date_joined, email, first_name, groups, id, is_active, is_staff, is_superuser, last_login, last_name, logentry, password, user_infos, user_permissions, username"
forms.py
class RegisterForm(forms.Form):
GRADE_CHOICES = (
(9,'9'), (10,'10'), (11,'11'), (12,'12') ,
)
curr_year = date.today().year
GRAD_YEAR_CHOICES = (
(curr_year,curr_year), (curr_year+1,curr_year+1), (curr_year+2,curr_year+2), (curr_year+3,curr_year+3) ,
)
first_name = forms.CharField(max_length = 25)
last_name = forms.CharField( max_length = 25)
emailid = forms.EmailField()
passwd1 = forms.CharField(max_length=100,widget=forms.PasswordInput)
passwd2 = forms.CharField(max_length=100,widget=forms.PasswordInput)
gradyear = forms.ChoiceField( choices=GRAD_YEAR_CHOICES)
grade = forms.ChoiceField( choices=GRADE_CHOICES)
pin = forms.IntegerField()
def clean(self):
cleaned_data = super(RegisterForm, self).clean()
print cleaned_data
if cleaned_data['passwd1'] != cleaned_data['passwd2']:
raise forms.ValidationError({'passwd1':['Password do not match']})
if User.objects.filter(email=cleaned_data['emailid']).count():
raise forms.ValidationError({'emailid':['Email already taken ']})
if User.objects.filter(pin=cleaned_data['pin']).count():
raise forms.ValidationError({'pin':['Pin already taken ']})
return cleaned_data
views.py
def signup(request):
print "signup"
if request.method == 'POST':
print "post signup"
form = RegisterForm(request.POST)
try:
if form.is_valid():
print form.cleaned_data
u = User.objects.create_user(form.cleaned_data['emailid'], form.cleaned_data['emailid'], form.cleaned_data['passwd1'] )
ui = UserInfo()
ui.user = u
ui.class_of = form.cleaned_data['gradyear']
ui.grade = form.cleaned_data['grade']
ui.balance = 0
print "Hi"
ui.pin = form.cleaned_data['pin']
print ui.pin
u.first_name = form.cleaned_data['first_name']
u.last_name = form.cleaned_data['last_name']
u.save()
ui.save()
user = authenticate(username=form.cleaned_data['emailid'], password=form.cleaned_data['passwd1'])
login(request,user)
print "after login in signup"
return redirect("/")
else:
print "error"
print form.errors
except:
raise
print "error here"
print form.errors
pass
#return render(request, 'student/register.html', {'form': form})
else:
form = RegisterForm()
return render(request, 'student/register.html', {'form': form})
models.py:
class UserInfo(models.Model):
user = models.OneToOneField(User, related_name='user_infos')
class_of = models.IntegerField()
#username = user.username
#fname = user.fname
#lname = user.last_name
#email = user.email
#Staff = user.is_staff
pub_date = models.DateTimeField( auto_now=True)
grade = models.IntegerField()
balance = models.DecimalField(max_digits=6, decimal_places=2)
pin = models.IntegerField()
#first_name = models.CharField(max_length = 25)
I don't think not be doing this right. Is there any way to add another column in a database another way?
You have "pin" field in your UserInfo model, but in forms.py you are trying to filter User model:
if User.objects.filter(pin=cleaned_data['pin']).count():
User model does not have "pin" field, so you are getting that error message.
Also I suggest you to learn and start using ModelForms: https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/
this is my views.py
def signup(request):
print "signup"
if request.method == 'POST':
print "post signup"
form = RegisterForm(request.POST)
try:
if form.is_valid():
print form.cleaned_data
u = User.objects.create_user(form.cleaned_data['emailid'], form.cleaned_data['emailid'], form.cleaned_data['passwd1'] )
ui = UserInfo()
ui.user = u
ui.class_of = form.cleaned_data['gradyear']
ui.grade = form.cleaned_data['grade']
ui.balance = 0
ui.save()
and in my forms.py i have:
class RegisterForm(forms.Form):
GRADE_CHOICES = (
(9,'9'), (10,'10'), (11,'11'), (12,'12') ,
)
curr_year = date.today().year
GRAD_YEAR_CHOICES = (
(curr_year,curr_year), (curr_year+1,curr_year+1), (curr_year+2,curr_year+2), (curr_year+3,curr_year+3) ,
)
first_name = forms.CharField(max_length = 25)
last_name = forms.CharField( max_length = 25)
emailid = forms.EmailField()
passwd1 = forms.CharField(max_length=100,widget=forms.PasswordInput)
passwd2 = forms.CharField(max_length=100,widget=forms.PasswordInput)
gradyear = forms.ChoiceField( choices=GRAD_YEAR_CHOICES)
grade = forms.ChoiceField( choices=GRADE_CHOICES)
def clean(self):
cleaned_data = super(RegisterForm, self).clean()
if cleaned_data['passwd1'] != cleaned_data['passwd2']:
raise forms.ValidationError({'passwd1':['Password do not match']})
if User.objects.filter(email=cleaned_data['emailid']).count():
raise forms.ValidationError({'emailid':['Email already taken ']})
return cleaned_data
why does everything print to the database except first_name and last_name??? (username, email, grade, gradyear, and password all save)
EDIT: This is my UserInfo
class UserInfo(models.Model):
user = models.OneToOneField(User, related_name='user_infos')
class_of = models.IntegerField()
#username = user.username
#fname = user.fname
#lname = user.last_name
#email = user.email
#Staff = user.is_staff
pub_date = models.DateTimeField( auto_now=True)
grade = models.IntegerField()
balance = models.DecimalField(max_digits=6, decimal_places=2)
#first_name = models.CharField(max_length = 25)
In the code provided, you never save first_name and last_name for User or UserInfo.
In def signup(request):, right after this line:
u = User.objects.create_user(form.cleaned_data['emailid'], form.cleaned_data['emailid'], form.cleaned_data['passwd1'] )
Try including this:
u.first_name = form.cleaned_data['first_name']
u.last_name = form.cleaned_data['last_name']
u.save()
forms.py
class UserProfileForm(forms.ModelForm):
phone = forms.CharField(max_length = 15,widget = forms.TextInput(attrs = {'placeholder':'Enter mobile no. ','class':''}))
profession = forms.CharField(max_length= 50,widget = forms.Select(choices = PROFESSION_CHOICES,attrs = {'class':''}))
#email = forms.EmailField(label='Email address',max_length = 75,widget = forms.TextInput(attrs={'placeholder':'Email address.','class':''}))
sex = forms.CharField(max_length = 20,label="I am :",widget=forms.Select(choices=SEX_CHOICES,attrs = {'class':''}))
first_name = forms.CharField(max_length = 50,widget = forms.TextInput(attrs={'placeholder':'Please enter your real name.','class':''}))
last_name = forms.CharField(max_length = 50,widget = forms.TextInput(attrs={'placeholder':'Enter last name.','class':''}))
location = forms.CharField(max_length = 50,widget = forms.TextInput(attrs={'placeholder':'Enter your current location','class':''}))
def clean_first_name(self):
first_name = self.cleaned_data['first_name']
if first_name == '':
raise forms.ValidationError("This field is required.")
return first_name
def save(self,*args,**kw):
self.instance.first_name = self.cleaned_data.get("first_name")
self.instance.last_name = self.cleaned_data.get("last_name")
self.instance.sex = self.cleaned_data.get("sex")
self.instance.location = self.cleaned_data.get("location")
self.instance.profession = self.cleaned_data.get("profession")
self.instance.phone = self.cleaned_data.get("phone")
self.instance.save()
return self.instance
class Meta:
model = User
fields = ('username','first_name','last_name','phone','sex','profession','location')
views.py
def profile(request,nav="profile",template="profile.html",context = {},extra_context = None):
if request.POST:
if 'profileFormSubmit' in request.POST:
pform = UserProfileForm(request.POST,instance = request.user)
if pform.is_valid():
try:
user = pform.save()
return redirect(profile,nav="profile")
except RuntimeError as e:
return HttpResponse(e)
error
The User could not be changed because the data didn't validate.
line
user = super(UserProfileForm,self).save(*args,**kw)
doubt
what changes am i supposed to make to get rid of this error
how am i supposed to change the , i have tried removing all the clean_field form methods , but still getting the same error , please help , thanks in advance.
You are calling save on your form before you clean. And you are calling save twice. Once at the start of the form save. And once at the end.
pform.is_valid() returns a boolean that you never check.
docs on modelforms
The form wasn't validating because I was using 'username' in my meta class of the UserProfileForm, which wasn't supposed to be there.