django updating user profile form - django

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.

Related

Django 1.8: add user to Modelform in views: not null constraint failed

I know there are a lot of similar questions here, but none of them seem to be working with my view in Django 1.8 with a ModelForm.
I have a user profile form that works as long as I have each required field in the template context, but I only want each logged in user to fill out their own form.
I'm doing something wrong here, and I'm not sure what the problem is. Can someone correct me? I've spent hours looking at other posts and trying various suggestions from SO. I'm getting "NOT NULL constraint failed: camp_userprofile.user_id"
Here's my models.py:
class UserProfile(models.Model):
user = models.OneToOneField(User)
picture = models.ImageField(upload_to='profile_images', blank=True)
city = models.CharField(max_length = 20)
needs_camp_bike = models.BooleanField(default=False)
diet_lifestyle = models.CharField(max_length = 200, choices=What_are_you, null=True, blank=True)
meal_restrictions = models.CharField(max_length = 200, blank= True)
other_restrictions = models.CharField(max_length=100, blank=True)
arrival_day = models.IntegerField(choices=Days)
departure_day = models.IntegerField(choices=Days)
date = models.DateTimeField(auto_now_add=True, blank=True)
def __str__(self):
return '%s %s %s %s %s %s %s %s %s' %(
self.user, self.picture, self.city,
self.needs_camp_bike,
self.diet_lifestyle, self.meal_restrictions, self.other_restrictions,
self.arrival_day, self.departure_day
)
My forms.py
class UserProfileForm(ModelForm):
class Meta:
Fish = "Fish"
Mammal = "Mammal"
Vegetarian = "Vegetarian"
Omnivore = "Omnivore"
Onions = "Onions"
Cucumber = "Cucumber"
Peppers = "Peppers"
Gluten_free = "Gluten_free"
Vegan = "Vegan"
Shellfish = "Shellfish"
Olives = "Olives"
Pork = "Pork"
Soy = "Soy"
Dairy = "Dairy"
Cilantro = "Cilantro"
Quinoa = "Quinoa"
Nightshades = "Nightshades"
Nuts = "Nuts"
Pescaterian = "Pescaterian"
Restrictions = (
(Mammal, "Mammal"),
(Onions, "Onions"),
(Cilantro, "Cilantro"),
(Soy, "Soy"),
(Dairy, "Dairy"),
(Quinoa, "Quinoa"),
(Pork, "Pork"),
(Olives, "Olives"),
(Dairy, "Dairy"),
(Peppers, "Peppers"),
(Cucumber, "Cucumber"),
(Nightshades, "Nightshades"),
(Nuts, "Nuts")
)
model = UserProfile
fields = ('picture', 'city',
'needs_camp_bike', 'diet_lifestyle',
'other_restrictions', 'arrival_day',
'departure_day', 'meal_restrictions')
widgets = {
'meal_restrictions': forms.widgets.CheckboxSelectMultiple(choices=Restrictions),
}
and my views.py
#login_required
def profile(request):
form = UserProfileForm(request.POST)
print(request.user)
if request.method == 'POST':
if form.is_valid():
form.save(commit=False)
form.user =request.user.username
form.save(commit=True)
else:
print(messages.error(request, "Error"))
return render(request, "profile.html", RequestContext(request, {'form': form, 'profile': profile,}))
You shouldn't do form.user = request.user.username, because form.user won't add the user to the form. You should capture the object that form.save(commit=false) returns, then assign the user to that object and save it.
Also you cannot assign a user field with username, username is only a string not User object. You should do this instead:
if form.is_valid():
userprofile = form.save(commit=False)
userprofile.user = request.user
userprofile.save()

django modelform saving issues

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')

IntegrityError error while saving value of to foreign key in django

Hey folks i am getting integrity error while saving my views .Please tell me what i am doing wrong
Here is my django model
class Ruleinfo(models.Model):
rule = models.IntegerField(null=False)
From = models.IPAddressField(null=True)
to = models.IPAddressField(null=True)
priority = models.ForeignKey('Priority',related_name='pri_no')
cisp =models.ForeignKey('Priority',related_name = 'CISP_no')
def __unicode__(self):
return u'%s' %(self.rule)
class Priority(models.Model):
pri = models.IntegerField(null = True)
Ruleno = models.ForeignKey('Ruleinfo',related_name = 'ruleno_no')
CISP = models.IntegerField(null = True)
def __unicode__(self):
return u'%s ' % (self.priority)
My model form is looking like .
class RuleInfoForm(ModelForm):
class Meta:
model = Ruleinfo
fields = ("rule","From","to")
here is my views.py
def multiwanrule_info(request):
data = {}
no_of_isp = MultiWAN.objects.all()
try:
form = RuleInfoForm(request.POST)
except:
pass
print "----------------------------printing form"
print form
if form.is_valid():
rl_frm = form.save(commit=False)
get_priorities = request.POST.getlist('priority')
get_cisp_info = request.POST.getlist('cisp')
rule_object = Ruleinfo()
for get_pri,get_ci in zip(get_priorities,get_cisp_info,):
pri_object = Priority.objects.get_or_create(Ruleno = rule_object)
pri_object.pri = get_pri
pri_object.CISP = get_ci
rl_frm.save()
else:
form = RuleInfoForm()
data['form'] = form
data['number_of_isp'] = no_of_isp
return render_to_response('networking.html',data)
I am getting the above error along this
networking_priority.Ruleno_id may not be NULL
help me out so that i could get back on track .
rule_object = Ruleinfo()
This just instantiates a new model object. It is not saved or assigned values. Since it is not saved it does not have an id value.
assigning your rule_object values: rule, from, to, priority, and cisp values, should fix your problem.

Checking to see if a database duplicate with Null field

I am trying to check and see if there is a duplicate entry in the database before adding an entry. Here are my current models --
class Education(models.Model):
school = models.CharField(max_length=100)
class_year = models.IntegerField(max_length=4, blank=True, null=True, choices=YEAR)
degree = models.CharField(max_length=100, blank=True, null=True)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
employments = models.ManyToManyField(Employment)
On the form, a user must enter a school. Class year and degree are optional. To check for duplicate entries, right now I have --
if form.is_valid() and request.POST['school']:
school = form.cleaned_data['school']
try:
school_object = Education.objects.get(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
except (Education.DoesNotExist):
school_object = Education(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
school_object.save()
profile.educations.add(school_object)
profile.save()
I am getting an ValueError if the class_date is not filled out. How to fix this and also when checking for duplicates? Thank you.
First, unless you've got a great reason you really shouldn't be accessing post variables without sending them through a form.
from django import forms
class MyForm(forms.form):
school = forms.CharField()
degree = forms.CharField(required=False)
class_year = forms.CharField(required=False)
def clean(self):
if not self.cleaned_data.has_key('degree'):
self.cleaned_data['degree'] = None
if not self.cleaned_data.has_key('class_year'):
self.cleaned_data['class_year'] = None
return self.cleaned_data
Then when you're processing the view:
...
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
try:
# NOTE that the objects.get method will raise MultipleObjectsReturned if the
# database has more than one object that matches the query
my_object = Education.objects.get(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
except Education.DoesNotExist:
my_object = Education(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
else:
form = MyForm()
...
In views:
if 'Add School' in request.POST.values():
form = EducationForm(request.POST)
if form.is_valid() and request.POST['school']:
school = form.cleaned_data['school']
try:
school_object = Education.objects.get(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
except (Education.DoesNotExist, ValueError):
school_object = Education(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
school_object.save()
profile.educations.add(school_object)
profile.save()
return redirect('edit_education')
Or, using get_or_create to simplify:
if 'Add School' in request.POST.values():
form = EducationForm(request.POST)
if form.is_valid() and request.POST['school']:
school = form.cleaned_data['school']
school_object, created = Education.objects.get_or_create(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
if created:
profile.educations.add(school_object)
profile.save()
return redirect('edit_education')
In forms:
YEAR = ([(x, x) for x in range(1970,2015)])
YEAR.append((0,'Select Year'))
YEAR.reverse()
class EducationForm(forms.Form):
school = forms.CharField()
class_year = forms.ChoiceField(choices=YEAR, required=False)
degree = forms.CharField(required=False)
def clean(self):
if not self.cleaned_data.get('class_year'):
self.cleaned_data['class_year'] = None
if not self.cleaned_data.get('degree'):
self.cleaned_data['degree'] = ''
return self.cleaned_data

modelform "object not callable" error

Ok, so I'm fairly new to Django, but have been reading both the online django book and the djangoproject documentation, but I can't seem to figure this error out:
I've got an 'Orders' model:
class Orders(models.Model):
client_id = models.ForeignKey(Client)
order_date = models.DateField(auto_now_add = True)
due_date = models.DateField()
completion_date = models.DateField(blank=True, null=True)
rush_order = models.BooleanField(default=False)
billing_option = models.ForeignKey(Billing)
patient_first_name = models.CharField(max_length=30)
patient_middle_name = models.CharField(max_length=30, blank=True)
patient_last_name = models.CharField(max_length=30)
client_patient_id = models.CharField(max_length=30, blank=True)
emodel_patient_id = models.CharField(max_length=30)
special_instructions = models.TextField(blank=True)
order_items = models.ManyToManyField(Order_Items)
def __unicode__(self):
return '%s : %s %s O: %s F: %s' % (self.client_id, self.patient_first_name, self.patient_last_name, self.order_date, self.completion_date)
class Meta:
ordering = ['client_id']
I've got a 'SearchOrderForm' modelform:
class SearchOrderForm(ModelForm):
class Meta:
model = Orders
exclude = ('rush_order', 'billing_option', 'client_patient_id', 'special_instructions', 'order_items',)
and I've got an 'order_status' function:
def order_status(request):
error = False
error_searching = False
if request.method == 'POST':
OrderFormSet = SearchOrderForm()
formset = OrderFormSet()
if formset.is_valid():
cd = formset.cleaned_data()
emodels_results = cd()
emodels_results = cd(queryset = Order.objects.filter(Q(patient_first_name=search)|Q(patient_last_name=search)|Q(client_id=search)))
patient_first_name = request.POST('patient_first_name', None)
if patient_first_name:
emodels_results = emodels_results(queryset = Order.objects.filter(patient_first_name=patient_first_name))
patient_last_name = request.POST('patient_last_name', None)
if patient_last_name:
emodels_results = emodels_results(queryset = Order.objects.filter(patient_last_name=patient_last_name))
client_id = request.POST('client_id', None)
if client_id:
emodels_results = emodels_results(queryset = Order.objects.filter(client_id=client_id))
return render_to_response('search_results.html', {'models': emodels_results})
else:
emodels_results = "Still messed up!"
return render_to_response('search_results.html', {'models': emodels_results})
else:
error_searching = True
form = SearchOrderForm()
return render_to_response('order_status.html', {'form': form, 'error': error, 'error_searching': error_searching})
I can fill out my form with no problems, but when I submit the form I get back the following error message:
Traceback:
File "C:\Python26\lib\site-packages\django\core\handlers\base.py" in get_response
92. response = callback(request, *callback_args, **callback_kwargs)
File "C:\emodel_tracking..\emodel_tracking\tracker\views.py" in order_status
105. formset = OrderFormSet()
Exception Type: TypeError at /accounts/profile/orderstatus/
Exception Value: 'SearchOrderForm' object is not callable
Does anyone know what I'm doing wrong with my SearchOrderForm that's causing Django to say that it is not callable?
I think you want either of these:
OrderFormSet = SearchOrderForm()
if OrderFormSet.is_valid():
formset = SearchOrderForm()
if formset.is_valid()
With the second way being the preferred syntax style. As a matter of nitpicking, Django offers a FormSet type which is different than the Form type so it is convention to refer to instances of Forms as "form":
form = SearchOrderForm()
if form.is_valid():
You are going to have some other problems with your code:
def order_status(request):
error = False
error_searching = False
if request.method == 'POST':
#instead of:
#OrderFormSet = SearchOrderForm()
#formset = OrderFormSet()
#instantiate an instance of your ModelForm
#(I'd normally name it "form")
formset = SearchOrderForm()
if formset.is_valid():
cd = formset.cleaned_data()
#cd is now a Python dictionary
#these next 2 lines don't make sense, what is your intention?
emodels_results = cd()
emodels_results = cd(queryset = Order.objects.filter(Q(patient_first_name=search)|Q(patient_last_name=search)|Q(client_id=search)))
#you've already used your form to process and clean
#the incoming POST data. use the cleaned data instead
#patient_first_name = request.POST('patient_first_name', None)
patient_first_name = cd.get('patient_first_name','')
#use data from the form's cleaned_data as in the line above
#I'm not sure what your intention is with how the emodels_results
#is but you'll need to rework that for it all to work
if patient_first_name:
emodels_results = emodels_results(queryset = Order.objects.filter(patient_first_name=patient_first_name))
patient_last_name = request.POST('patient_last_name', None)
if patient_last_name:
emodels_results = emodels_results(queryset = Order.objects.filter(patient_last_name=patient_last_name))
client_id = request.POST('client_id', None)
if client_id:
emodels_results = emodels_results(queryset = Order.objects.filter(client_id=client_id))
return render_to_response('search_results.html', {'models': emodels_results})
else:
emodels_results = "Still messed up!"
return render_to_response('search_results.html', {'models': emodels_results})
else:
error_searching = True
form = SearchOrderForm()
return render_to_response('order_status.html', {'form': form, 'error': error, 'error_searching': error_searching})