Django User Registration Form KeyError - django

When requesting a blank RegisterForm, I get a KeyError. I believe that when I click the link on the site, I submit a GET request to the register method and the form1 = RegisterForm() line fires. I believe there is something wrong with my RegisterForm class but I can't figure out what it is. I'm using the User model and UserCreationForm. Any help is greatly appreciated.
KeyError at /profile/pm/register u'username'
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/exception.py" in inner
39. response = get_response(request)
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _legacy_get_response
249. response = self._get_response(request)
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vagrant/project/tmp/user_profile/views.py" in register
77. form1 = RegisterForm()
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/forms.py" in __init__
97. self.fields[self._meta.model.USERNAME_FIELD].widget.attrs.update({'autofocus': ''})
Exception Type: KeyError at /profile/pm/register
Exception Value: u'username'
views.py
def register(request, user_type):
if user_type not in ["pm", "hm"]:
raise Http404
if request.user.is_authenticated():
return redirect(reverse('index'))
if user_type == 'hm':
userTypeChoices = [Profile.RecruiterAgency, Profile.RecruiterInternal, Profile.HiringManager]
else:
userTypeChoices = [Profile.PMEmployee, Profile.PMContractConsultant, Profile.PMBoth]
if request.method =="POST":
# accept tos
if 'accepted_tos' in request.POST:
return acceptedTOS(request)
form1 = RegisterForm(request.POST)
form2 = ProfileForm(request.POST)
if form1.is_valid() and form2.is_valid():
user = form1.save()
profile = Profile()
profile.user_id = user.id
profile.company = form2.cleaned_data["company"]
profile.phone = form2.cleaned_data["phone"]
profile.user_type = form2.cleaned_data["user_type"]
profile.save()
if profile.user_type in [Profile.PMEmployee, Profile.PMContractConsultant, Profile.PMBoth]:
prospect = Prospect(profile=profile)
prospect.save()
else:
employer = Employer(profile=profile)
employer.save()
return JsonResponse({'message':'success'})
else:
return JsonResponse({'message':form2.errors})
else:
form1 = RegisterForm()
form2 = ProfileForm()
return render(request, 'profile/register.html', {'form1':form1, 'form2':form2, 'userType':user_type, 'userTypeChoices':userTypeChoices})
forms.py
class RegisterForm(UserCreationForm):
email = forms.EmailField(label = "Email")
first_name = forms.CharField(label = "First name")
last_name = forms.CharField(label = "Last name")
class Meta:
model = User
fields = ("email", "first_name", "last_name")
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise forms.ValidationError('Email already in use.')
return email
def save(self, commit=True):
user = super(RegisterForm, self).save(commit=False)
user.username = self.cleaned_data["email"]
if commit:
user.save()
return user
models.py
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
phone = models.CharField(max_length=200, null=True, blank=True)
RecruiterAgency = 'ra'
RecruiterInternal = 'ri'
HiringManager = 'hm'
PMEmployee = 'pe'
PMContractConsultant = 'pc'
PMBoth = 'pm'
USER_TYPE_CHOICES = (
(RecruiterAgency, 'Recruiter - Agency'),
(RecruiterInternal, 'Recruiter - Internal'),
(HiringManager, 'Hiring Manager'),
(PMEmployee, 'PM - Employee'),
(PMContractConsultant, 'PM - Contract / Consultant'),
(PMBoth, 'PM - Both'),
)
user_type = models.CharField(max_length=2, choices=USER_TYPE_CHOICES, default=RecruiterAgency)
company = models.CharField(max_length=200, null=True, blank=True)
bio = models.TextField(null=True, blank=True)
accepted_tos = models.BooleanField(default=False)
profile_photo = models.ImageField(null=True, blank=True, upload_to="avatar")
def __str__(self):
return "%s's profile" % self.user.email
class Prospect(models.Model):
profile = models.OneToOneField(Profile, on_delete=models.CASCADE, null=True, blank=True, related_name="profile_prospects")
RestrictedCompany = models.ForeignKey(RestrictedCompany, on_delete=models.CASCADE, null=True, blank=True, related_name="company_prospects")
badge = models.ManyToManyField(Badge, blank=True, related_name="badge_prospects")
certification = models.ManyToManyField(Certification, blank=True, related_name="certification_prospects")
LargestProject1 = 'lp1'
LargestProject2 = 'lp2'
LargestProject3 = 'lp3'
LargestProject4 = 'lp4'
LargestProject5 = 'lp5'
LARGEST_PROJECT_CHOICES = (
(LargestProject1, '$1-100,000'),
(LargestProject2, '$100,001-$500,000'),
(LargestProject3, '$500,001-$1,000,000'),
(LargestProject4, '$1,000,001-$5,000,000'),
(LargestProject5, '$5,000,001+'),
)
largest_project = models.CharField(max_length=3, choices=LARGEST_PROJECT_CHOICES, default=LargestProject1)
add_to_pool = models.BooleanField(default=False)
LargestTeam1 = 'lt1'
LargestTeam2 = 'lt2'
LargestTeam3 = 'lt3'
LargestTeam4 = 'lt4'
LargestTeam5 = 'lt5'
LargestTeam6 = 'lt6'
LARGEST_TEAM_CHOICES = (
(LargestTeam1, '0-5'),
(LargestTeam2, '6-10'),
(LargestTeam3, '11-20'),
(LargestTeam4, '21-50'),
(LargestTeam5, '51-100'),
(LargestTeam6, '100+'),
)
largest_team = models.CharField(max_length=3, choices=LARGEST_TEAM_CHOICES, default=LargestTeam1)
Contract = 'ct'
FullTimeEmployee = 'fe'
Both = 'bo'
Position_Type_CHOICES = (
(Contract, 'Contract'),
(FullTimeEmployee, 'Full-Time Employee'),
(Both, 'Both'),
)
position_type = models.CharField(max_length=2, choices=Position_Type_CHOICES, default=Contract)
resume = models.FileField(null=True, blank=True, upload_to="resume")
EntryLevel = 'el'
Junior = 'jn'
Professional = 'pr'
TIER_CHOICES = (
(EntryLevel, 'Entry-Level'),
(Junior, 'Junior'),
(Professional, 'Professional'),
)
tier = models.CharField(max_length=2, choices=TIER_CHOICES, default=EntryLevel)
billable_rate = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
annual_salary = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
total_years_exp = models.DecimalField(max_digits=4, decimal_places=2, null=True, blank=True)
def __str__(self):
return "%s" % self.profile.user.email
class Employer(models.Model):
profile = models.OneToOneField(Profile, on_delete=models.CASCADE, null=True, blank=True, related_name="profile_employers")
title = models.CharField(max_length=200, null=True, blank=True)
street = models.CharField(max_length=200, null=True, blank=True)
city = models.CharField(max_length=200, null=True, blank=True)
zip = models.CharField(max_length=200, null=True, blank=True)
state = models.CharField(max_length=200, null=True, blank=True)
country = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
return "%s" % self.profile.user.email

The comments were correct and very helpful! I needed to rename the "email" field on the RegisterForm to "username":
class RegisterForm(UserCreationForm):
username = forms.EmailField(label = "Email")
first_name = forms.CharField(label = "First name")
last_name = forms.CharField(label = "Last name")
class Meta:
model = User
fields = ("username", "first_name", "last_name")
def clean_email(self):
username = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise forms.ValidationError('Email already in use.')
return username
def save(self, commit=True):
user = super(RegisterForm, self).save(commit=False)
user.username = self.cleaned_data["email"]
if commit:
user.save()
return user

You have come across this issue where the UserCreationForm crashes if USERNAME_FIELD (in your case username) is not a form field.
The issue only affects Django 1.10, it doesn't affect earlier versions of Django. It will be fixed in the upcoming Django 1.10.1 release.

Related

matching query does not exist Error in Django (OneToOneField)

Please help me I don't know what I am doing wrong I am getting an error
Available_time matching query does not exist.
I use here OneToOneField from the Available_time database from Sunday to Saturday. I don't understand why this error is showing.
class Available_time(models.Model):
timezone = models.TimeField(auto_now=False, auto_now_add=False)
nickname = models.CharField(max_length=30, default='IST_time')
def __str__(self):
return str(self.nickname)
class RMDatabase(models.Model):
user_id = models.ForeignKey(User, on_delete=models.CASCADE)
date_at = models.DateTimeField(auto_now=True)
country= models.CharField(max_length=100, blank=True)
province = models.CharField(max_length=100, blank=True)
city = models.CharField(max_length=100, blank=True)
contact = models.CharField(max_length=100, blank=True)
countryCode = models.CharField(max_length=100, blank=True)
motherTongue = models.CharField(max_length=100, blank=True)
secondSpokenLang = models.CharField(max_length=100, blank=True)
secondSpokenLangReason = models.CharField(max_length=100, blank=True)
interstedIn = models.CharField(max_length=100, blank=True)
skillLevel = models.CharField(max_length=100, blank=True)
qualification = models.CharField(max_length=100, blank=True)
qualificationAwardedBy = models.CharField(max_length=100, blank=True)
qualificationFile= models.FileField(upload_to='folder/')
videolink = models.CharField(max_length=100, blank=True)
preferredDayTime = models.CharField(max_length=100, blank=True)
sunday= models.ManyToManyField(Available_time,blank=True, related_name='sunday')
monday = models.ManyToManyField(Available_time, blank=True,related_name='monday')
tuesday= models.ManyToManyField(Available_time,blank=True, related_name='tuesday')
wednesday = models.ManyToManyField(Available_time, blank=True,related_name='wednesday')
thrusday= models.ManyToManyField(Available_time,blank=True, related_name='thrusday')
friday = models.ManyToManyField(Available_time, blank=True,related_name='friday')
saturday = models.ManyToManyField(Available_time,blank=True, related_name='saturday')
def __str__(self):
return self.motherTongue
**My view.py
here I simple takin input from the user and save the database. the problem I facing from **if request.POST.get('sunday-evening'): to till end if conditions. if remove those lines then working fine.
def MNFRM(request):
x= RMDatabase()
# if request.user.is_active:
# if x.objects.filter(user_id=request.user).exists():
# return render(request, 'relationshipmanager/userexists.html')
if request.method == 'POST':
x.user_id = request.user
x.country = country_list[str(request.POST.get('country')).upper()]
x.province = request.POST.get('state')
x.city = request.POST.get('city')
x.contact = request.POST.get('number')
x.countryCode = request.POST.get('code')
for it in ["motherTounge", "nativLanguage", "mediumOfInstruction", "qualifiedInParticularLanguage"]:
if request.POST.get(it):
s = it+','
x.secondSpokenLangReason += s
x.motherTongue = request.POST.get('motherTongue')
x.secondSpokenLang=request.POST.get('secondSpokenLang')
for it in ["Script Writing", "Producing Films", "Directing", "Acting", "Editing", "Animation"]:
if request.POST.get(it):
s = it+','
x.interstedIn += s
x.skillLevel=request.POST['SkillLevel']
x.qualification=request.POST.get('qualification')
x.qualificationAwardedBy=request.POST.get('qualificationAwardedBy')
x.qualificationFile=request.FILES['qualificationFile']
x.videolink=request.POST.get('videolink')
x.save()
if request.POST.get('sunday-evening'):
x.sunday.add(Available_time.objects.get(nickname='evening-time'))
if request.POST.get('sunday-afternoon'):
x.sunday.add(Available_time.objects.get(nickname='afternoon-time'))
if request.POST.get('sunday-morning'):
x.sunday.add(Available_time.objects.get(nickname='morning-time'))
if request.POST.get('monday-evening'):
x.monday.add(Available_time.objects.get(nickname='evening-time'))
if request.POST.get('monday-afternoon'):
x.monday.add(Available_time.objects.get(nickname='afternoon-time'))
if request.POST.get('monday-morning'):
x.monday.add(Available_time.objects.get(nickname='morning-time'))
if request.POST.get('tuesday-evening'):
x.tuesday.add(Available_time.objects.get(nickname='evening-time'))
if request.POST.get('tuesday-afternoon'):
x.tuesday.add(Available_time.objects.get(nickname='afternoon-time'))
if request.POST.get('tuesday-morning'):
x.tuesday.add(Available_time.objects.get(nickname='morning-time'))
if request.POST.get('wednesday-evening'):
x.wednesday.add(Available_time.objects.get(nickname='evening-time'))
if request.POST.get('wednesday-afternoon'):
x.wednesday.add(Available_time.objects.get(nickname='afternoon-time'))
if request.POST.get('wednesday-morning'):
x.wednesday.add(Available_time.objects.get(nickname='morning-time'))
if request.POST.get('thrusday-evening'):
x.thrusday.add(Available_time.objects.get(nickname='evening-time'))
if request.POST.get('thrusday-afternoon'):
x.thrusday.add(Available_time.objects.get(nickname='afternoon-time'))
if request.POST.get('thrusday-morning'):
x.thrusday.add(Available_time.objects.get(nickname='morning-time'))
if request.POST.get('friday-evening'):
x.friday.add(Available_time.objects.get(nickname='evening-time'))
if request.POST.get('friday-afternoon'):
x.friday.add(Available_time.objects.get(nickname='afternoon-time'))
if request.POST.get('friday-morning'):
x.friday.add(Available_time.objects.get(nickname='morning-time'))
if request.POST.get('saturday-evening'):
x.saturday.add(Available_time.objects.get(nickname='evening-time'))
if request.POST.get('saturday-afternoon'):
x.saturday.add(Available_time.objects.get(nickname='afternoon-time'))
if request.POST.get('saturday-morning'):
x.saturday.add(Available_time.objects.get(nickname='morning-time'))
x.save()
# email_message = EmailMessage(
# "RM Registration Successful",
# "Hi "+str(request.user.first_name)+' '+str(request.user.last_name) +
# ",\nYou have successfully registered for our Relationship Manager programme.",
# settings.EMAIL_HOST_USER,
# [request.user.email]
# )
# email_message.send()
subject= "Relationship Manager form is successfully submitted "+ "."
from_email = settings.EMAIL_HOST_USER
to = request.user.email
html_content = render_to_string('relationshipmanager/email.html') # render with dynamic value
# Strip the html tag. So people can see the pure text at least.
text_content = strip_tags(html_content)
# create the email, and attach the HTML version as well.
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()
return redirect('base')
# return HttpResponse('Thanks your application has successfully registered, we will notify you via email about your application status.')
# z = xyz()
# print(z)
# return render(request, 'lpp/lppreg.html', {})
return render(request,'relationshipmanager/rmreg.html',{})

Django error: The Items could not be created because the data didn't validate

I get the following error:
ValueError at /create-items/
The Items could not be created because the data didn't validate., and can't find out what the issue is...
Views.py
def createMulitpleItemsPage(request):
currency = '€'
ItemFormSet = modelformset_factory(Items, form=CreateItemFormset, extra=1)
qs = Items.objects.none()
user = request.user.profile
formset = ItemFormSet(request.POST or None, queryset=qs, form_kwargs={'user': user})
# Create multiple items
if request.method == 'GET':
user = request.user.profile
ItemFormSet = modelformset_factory(Items, form=CreateItemFormset, extra=1)
qs = Items.objects.none()
formset = ItemFormSet(request.POST or None, queryset=qs, form_kwargs={'user': user})
context = {'formset': formset}
if request.method == 'POST':
print('printing POST: ', request.POST)
print('printing Errors: ', formset.errors)
if formset.is_valid():
formset = CreateItemFormset(user=request.user.profile, data=request.POST)
parent = formset.save(commit=False)
parent = formset.save()
for form in formset:
newitems = form.save(commit=False)
newitems.user = request.user.profile
newitems.save()
return redirect('items')
return render(request, 'base/mass_create_items.html', context)
Forms.py
class CreateItemFormset(ModelForm):
def __init__(self, user, *args, **kwargs):
super(CreateItemFormset, self).__init__(*args, **kwargs)
qs = Categories.objects.filter(user=user)
self.fields['item_category'] = ModelChoiceField(queryset=qs)
class Meta:
model = Items
fields = ['item_name', 'item_category', 'item_start_date', 'item_end_date', 'item_purchase_price', 'item_rest_value']
Models.py
class Items(models.Model):
user = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True, blank=True)
item_name = models.CharField(max_length=200, null=False, blank=False)
item_category = models.ForeignKey(Categories, null=True, blank=True, on_delete=models.SET_NULL)
item_created_at = models.DateTimeField(auto_now_add=True, null=True, blank=False)
item_updated_at = models.DateTimeField(auto_now=True, null=True, blank=False)
item_start_date = models.DateField(null=True, blank=False)
item_end_date = models.DateField(null=True, blank=False)
item_purchase_price = models.FloatField(null=True, blank=False)
item_rest_value = models.FloatField(default=0, null=True, blank=False)
item_saving_goal = models.FloatField(default=0, null=True, blank=False)
item_date_delta = models.FloatField(default=0, null=True, blank=False)
item_days_passed = models.FloatField(default=0, null=True, blank=False)
item_currently_saved = models.FloatField(default=0, null=True, blank=False)
item_percentage_saved = models.FloatField(default=0.01, null=True, blank=False)
item_monthly_saving = models.FloatField(default=0, null=True, blank=False)
def save(self, *args, **kwargs):
self.item_saving_goal = self.item_purchase_price - self.item_rest_value
self.item_date_delta = (self.item_end_date.year - self.item_start_date.year) * 12 + ( self.item_end_date.month - self.item_start_date.month )
self.item_days_passed = (date.today().year - self.item_start_date.year) * 12 + ( date.today().month - self.item_start_date.month )
self.item_currently_saved = self.item_saving_goal * (self.item_days_passed / self.item_date_delta )
self.item_percentage_saved = self.item_currently_saved / self.item_saving_goal * 100
self.item_monthly_saving = self.item_saving_goal / self.item_date_delta
super().save(*args, **kwargs)
Error looks like this:
Internal Server Error: /create-items/
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/django/core/handlers/exception.py",
line 47, in inner
response = get_response(request)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/django/core/handlers/base.py",
line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/django/contrib/auth/decorators.py",
line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/Users/jelledekker/Library/Mobile Documents/com~apple~CloudDocs/Django/Aurelian web/base/views.py", line
304, in createMulitpleItemsPage
parent = formset.save(commit=False)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/django/forms/models.py",
line 458, in save
raise ValueError(
ValueError: The Items could not be created because the data didn't validate.
You are testing the formset for validity before binding it to POST!
if formset.is_valid():
formset = CreateItemFormset(user=request.user.profile, data=request.POST)
Think those two lines need to be reversed.

Data from my Django form is not added to my database cause I cannot view it on the webpage

I am trying to build a project management system and have to add client to my database. For this I have created a form as below
forms.py
class AddClientForm(forms.Form):
email = forms.EmailField(label="Email", max_length=50, widget=forms.EmailInput(attrs={"class":"form-control"}))
password = forms.CharField(label="Password", max_length=50, widget=forms.PasswordInput(attrs={"class":"form-control"}))
first_name = forms.CharField(label="First Name", max_length=50, widget=forms.TextInput(attrs={"class":"form-control"}))
last_name = forms.CharField(label="Last Name", max_length=50, widget=forms.TextInput(attrs={"class":"form-control"}))
username = forms.CharField(label="Username", max_length=50, widget=forms.TextInput(attrs={"class":"form-control"}))
phone = forms.CharField(label="Phone", max_length=15, widget=forms.TextInput(attrs={"class":"form-control"}))
#For Displaying Projects
try:
projects = Projects.objects.all()
project_list = []
for project in projects:
single_project = (project.id, project.project_name)
project_list.append(single_project)
except:
project_list = []
#For Displaying Contracts
try:
contracts = Contracts.objects.all()
contract_list = []
for contract in contracts:
single_contract = (contract.id, contract.contract_name)
contract_list.append(single_contract)
except:
contract_list = []
project_name = forms.ChoiceField(label="Project", choices=project_list, widget=forms.Select(attrs={"class":"form-control"}))
contract_id = forms.ChoiceField(label="Contract", choices=contract_list, widget=forms.Select(attrs={"class":"form-control"}))
location = forms.ChoiceField(label="Location", choices=States, widget=forms.Select(attrs={"class":"form-control"}))
Then i have created the following views.py
def add_client(request):
form = AddClientForm()
context = {
"form": form
}
return render(request, 'admintemplate/add_client_template.html', context)
def add_client_save(request):
if request.method != "POST":
messages.error(request, "Invalid Method")
return redirect('add_client')
else:
form = AddClientForm(request.POST, request.FILES)
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
phone = form.cleaned_data['phone']
location = form.cleaned_data['location']
project_id = form.cleaned_data['project_name']
contract_id = form.cleaned_data['contract_id']
try:
user = CustomUser.objects.create_user(username=username, password=password, email=email, first_name=first_name, last_name=last_name, user_type=3)
user.clients.location = location
user.client.primaryphone = phone
project_obj = Projects.objects.get(id=project_id)
user.clients.project_id = project_obj
contract_obj = Contracts.objects.get(id=contract_id)
user.clients.contract_id = contract_obj
user.clients.save()
messages.success(request, "Client Added Successfully!")
return redirect('add_client')
except:
messages.error(request, "Failed to Add Client!")
return redirect('add_client')
else:
return redirect('add_client')
And my models.py is as follows
class Clients(models.Model):
id = models.AutoField(primary_key=True)
admin = models.OneToOneField(CustomUser, on_delete = models.CASCADE)
primaryphone = models.CharField(max_length=15, unique=True)
location = models.CharField(max_length=30, choices=States)
project_id = models.ForeignKey(Projects, on_delete=models.DO_NOTHING, default=1)
contract_id = models.ForeignKey(Contracts, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = models.Manager()
I am not sure why the data is not being saved in the clients model. ANy help would be appreciated.

Saving formset when a compulsory field was not supplied?

I get an error "NOT NULL constraint failed" when I try to save a formset in an update view and the formset has had new forms added. I think the reason is that the database has a required field (journal_entry) that isn't part of the Formset ModelForm. So when the formset is attempted to be saved lineitem_formset.save() I get the error.
How can I add this required field value before saving the formset?
View.py
#login_required
def entries_update(request, pk):
journal_entry = get_object_or_404(JournalEntry, pk=pk)
journal_entry.date = journal_entry.date.strftime('%Y-%m-%d') #Convert date format to be suitable for Datepicker input.
journal_entry_form = JournalEntryForm(instance=journal_entry)
LineItemFormSet = modelformset_factory(LineItem, fields=('ledger','description','project','cr','dr'), extra=2)
line_items = LineItem.objects.filter(journal_entry=journal_entry)
lineitem_formset = LineItemFormSet(queryset=line_items)
if request.method == 'POST':
lineitem_formset = LineItemFormSet(request.POST)
journal_entry_form = JournalEntryForm(request.POST, instance=journal_entry)
if lineitem_formset.is_valid() and journal_entry_form.is_valid:
lineitem_formset.save() <-- ERROR HAPPENS HERE
journal_entry_form.save()
messages.success(request, "Journal entry successfully updated.")
return HttpResponseRedirect(reverse('journal:entries_show_detail', kwargs={'pk': journal_entry.id}) )
Models.py
class JournalEntry(models.Model):
# User needs to be set back to compulsory !!!
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True, blank=True)
date = models.DateField(null=False, blank=False)
TYPE = (
('BP', 'Bank Payment'),
('YE', 'Year End'),
('JE', 'Journal Entry')
)
type = models.CharField(
max_length=2,
choices=TYPE,
blank=True,
default='0'
)
description = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
if self.description:
return self.description
else:
return 'Journal Entry' + str(self.id)
class Meta(object):
ordering = ['id']
verbose_name_plural = 'Journal entries'
class LineItem(models.Model):
journal_entry = models.ForeignKey(JournalEntry, on_delete=models.CASCADE) <--- This is the field that needs to be set.
ledger = models.ForeignKey(Ledger, on_delete=models.PROTECT)
description = models.CharField(max_length=255, null=True, blank=True)
project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True)
cr = models.DecimalField(max_digits=8, decimal_places=2, null=True, blank=True)
dr = models.DecimalField(max_digits=8, decimal_places=2, null=True, blank=True)
STATUS = (
('0', 'Not reconciled'),
('1', 'Draft'),
)
status = models.CharField(
max_length=1,
choices=STATUS,
default='0'
)
reconciliation_date = models.DateField(null=True, blank=True)
#def __str__(self):
# return self.description
class Meta(object):
ordering = ['id']
forms.py
class JournalEntryForm(ModelForm):
def clean_date(self):
data = self.cleaned_data['date']
#Check date is not more than 30d future
if data > (datetime.date.today() + datetime.timedelta(30)):
raise ValidationError('Date cannot be more than 30d future')
if data < (datetime.date.today() - datetime.timedelta(90)):
raise ValidationError('Date cannot be more than 90d past')
return data
class Meta:
model = JournalEntry
fields = ['date','description']
widgets = {'date': DateTypeInput()}
class LineItemForm(ModelForm):
class Meta:
model = LineItem
fields = ['ledger','description','project','cr','dr']
# This init disallows empty formsets
def __init__(self, *arg, **kwarg):
super(LineItemForm, self).__init__(*arg, **kwarg)
self.empty_permitted = False
def clean(self):
cr = self.cleaned_data['cr']
dr = self.cleaned_data['dr']
if cr == None and dr == None:
raise ValidationError('You must enter a CR or DR.')
if cr and dr:
raise ValidationError('You must enter a CR or DR, not both.')
Thanks to #Iain Shelvington again. Edited the following lines to use inline_formset and now works:
LineItemFormSet = inlineformset_factory(JournalEntry, LineItem, fields=('ledger','description','project','cr','dr'), extra=2)
and:
lineitem_formset = LineItemFormSet(request.POST, instance=journal_entry)

Forms in Django. How to initialize model field from form?

In models.py:
class Client(AbstractBaseUser):
username = models.CharField(max_length=32, unique=True)
email = models.EmailField('email address', unique=True, db_index=True)
avatar = models.ImageField('avatar', upload_to='avatars')
id = id(object)
class Order(models.Model):
class Meta():
db_table = 'order'
short_desc = models.CharField(max_length=30)
subject = models.ForeignKey(Subject, blank=True)
user_id = models.ForeignKey('Client', to_field='id', related_name='client_id', default='0', blank=True)
performer_id = models.ForeignKey('Client', to_field='id', related_name='performer_id', default='0', blank=True)
worktype = models.ForeignKey(Type, blank=True)
level = models.IntegerField(default=0, blank=True)
readiness = models.BooleanField(default=False, blank=True)
description = models.TextField(max_length=2000, blank=True)
file = models.FileField(upload_to='orderfiles', blank=True)
#maxdate = models.DateField(blank=True)
addate = models.DateField(auto_now=True, blank=True)
price = models.IntegerField(max_length=10, blank=True)
responses = models.IntegerField(blank=True)
In forms.py:
class AddOrderForm(forms.ModelForm):
short_desc = forms.CharField(widget=forms.TextInput,label="Краткое описание(послужит именем)")
subject = forms.ModelChoiceField(queryset=Subject.objects.all(), label="Предмет")
worktype = forms.ModelChoiceField(queryset=Type.objects.all(), label="Тип")
level = forms.IntegerField(widget=forms.TextInput,label="Уровень сложности (от 1 до 5)")
description = forms.CharField(widget=forms.TextInput,label="Полное описание")
#maxdate = forms.DateField(widget=forms.TextInput,label="maxdate")
price = forms.IntegerField(widget=forms.TextInput,label="Ваша цена")
responses = forms.IntegerField(widget=forms.TextInput,label="Кол-во ответов на заказ")
class Meta:
model = Order
fields = ['short_desc', 'level', 'description', 'price', 'responses', 'subject', 'worktype']
In views.py:
def addorder(request, user_id):
"""
Adding Order view
"""
if request.POST:
form = AddOrderForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
return redirect('/')
auth1 = auth.get_user(request).username
return render_to_response('customer.html', { 'form': form,'username' : auth1}, context_instance=RequestContext(request))
I need the field user_id in class Order to be initialized immediately after adding order(). Where should I do it and in which way? I need something like this logic: Client adds an Order through AddOrderForm and then user_id field of just added object of class Order has to be initialized with an object of class Client, whose id equals user_id in parameters of addorder() function.
You can do that using commit=False while saving the form. This is typical way of saving the object using model form which has fewer fields.
def addorder(request, user_id):
"""
Adding Order view
"""
if request.POST:
form = AddOrderForm(request.POST)
if form.is_valid():
order = form.save(commit=false)
order.client_id = Client.objects.get(id=user_id)
order.save()
return redirect('/')
else:
return redirect('/')
auth1 = auth.get_user(request).username
return render_to_response('customer.html',
{ 'form': form,'username' : auth1},
context_instance=RequestContext(request))
Disclaimer: Handle errors e.g. Client.objects.get() may fail. Use appropriate fields to search.