Hej,
I have multiple options created by an SQL Select, one Example looks like this:
<select name="FirmaID" class="selectbox" id="id_FirmaID">
<option value="1" selected="">Westcoast Computer</option>
<option value="2">AppleNet</option>
<option value="9">amy.rau.codes</option>
<option value="11">Cybershield IVS</option>
</select>
You can see value is correct the ID of this Company, the problem is if I click on save its not saving. But if I change my queryset that the output looks like:
<option value="1" selected="">1</option>
then it's saving fine. But this looks not user-friendly. Why is Django try to save the text behind the value and not the value?
My view looks like this (is working for other forms but without this options field.
def addKunder(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = AddKunder(request.user.id, request.POST)
# check whether it's valid:
if form.is_valid():
form.save()
return HttpResponseRedirect('/pyOekonomi/kunder/')
# if a GET (or any other method) we'll create a blank form
else:
print ('somethin goes wrong')
form = AddKunder(request.user.id)
return render(request, 'pyOekonomi/modules/kunder/add.html', {'form': form})
Forms look like:
class AddKunder(forms.ModelForm):
Firma = forms.CharField(widget=forms.TextInput(attrs={'class': 'input_app', 'autofocus': True}),
label='Firma',
required=False)
Adresse = forms.CharField(widget=forms.TextInput(attrs={'class': 'input_app'}),
label='Adresse',
required=False)
Postnummer = forms.IntegerField(widget=forms.TextInput(attrs={'class': 'input_app'}),
label='Postcode',
required=False)
Byen = forms.CharField(widget=forms.TextInput(attrs={'class': 'input_app'}),
label='By',
required=False)
Land = forms.ModelChoiceField(widget=forms.Select(attrs={'class': 'countryselectbox'}),
queryset=CountryList.objects.values_list('countryname', flat=True).order_by('code'),
initial='Denmark',
to_field_name='countryname',
required=False)
CVRCountrycode = forms.ModelChoiceField(widget=forms.Select(attrs={'class': 'countryselectbox'}),
label='CVR Landkode',
queryset=CountryList.objects.values_list('code', flat=True).order_by('code'),
initial='DK',
to_field_name='code',
required=False)
FirmaID = forms.ModelChoiceField(queryset=None,
widget=forms.Select(attrs={'class': 'selectbox'}),
label='Firma',
to_field_name='ID',
empty_label=None)
#, queryset=FirmaModule.objects.values_list('Firmanavn', flat=True).filter(UserID=self.user).order_by('Firmanavn'), to_field_name='ID', empty_label=None)
class Meta:
model = FirmaModule
fields = ['Firmanavn', 'ID']
def __init__(self, user, *args, **kwargs):
super(AddKunder, self).__init__(*args, **kwargs)
self.fields['FirmaID'].queryset = FirmaModule.objects.filter(UserID=user)
#active = forms.BooleanField()
CVR = forms.IntegerField(widget=forms.TextInput(attrs={'class': 'input_app'}),label='CVR Nummer', required=False)
Kundenummer = forms.CharField(widget=forms.TextInput(attrs={'class': 'input_app' }), label='Kundenummer', required=True)
class Meta:
model = Kunder
labels = {
'Byen': 'By',
'CVRCountrycode': 'Landekode',
'CVR': 'CVR Nummer',
'active': 'er aktiv',
'IsFirmaKunde': 'Firmakunde',
'FirmaID': 'Firma',
'EMail': 'E-Mail Adresse'
}
fields = ['Kundenummer', 'FirmaID', 'Efternavn', 'Fornavn', 'Adresse', 'Telefon', 'Postnummer', 'Byen', 'Land', 'CVRCountrycode', 'CVR', 'active', 'IsFirmaKunde', 'UserID', 'EMail', 'Firma']
models:
class Kunder(models.Model):
ID = models.AutoField(primary_key=True)
Kundenummer = models.IntegerField('Kundenummer', unique=True)
Firma = models.CharField('Firma', max_length=128, null=True)
Efternavn = models.CharField('Efternavn', max_length=128)
Fornavn = models.CharField('Fornavn', max_length=128)
FirmaID = models.IntegerField('FirmaID')
UserID = models.IntegerField('UserID')
Adresse = models.CharField('Adresse', max_length=128, null=True)
Telefon = models.CharField('Telefon', max_length=32, null=True)
Postnummer = models.IntegerField('Postnummer', null=True)
Byen = models.CharField('Byen', max_length=100, null=True)
Land = models.CharField('Land', max_length=32, null=True)
CVRCountrycode = models.CharField('CVRCountrycode', max_length=3, null=True)
CVR = models.IntegerField('CVR', null=True)
active = models.BooleanField(default = False)
IsFirmaKunde = models.BooleanField(default = False)
EMail = models.EmailField('EMail', max_length=128, null=True)
def __str__(self):
return self.Firma
I fixed it myself.
Changed Model from
FirmaID = models.IntegerField('FirmaID')
to
FirmaID = models.ForeignKey('FirmaModule', on_delete=models.CASCADE,)
Related
I'm working on a timesheet based system currently. I am getting a Foreign Key constraint failure when I am trying to assign the foreign key of one model to the other one.
Here are the two models
class Timesheet(models.Model):
id = models.CharField(primary_key=True, max_length=50, blank=True, unique=True, default=uuid.uuid4)
First_Name = models.CharField(max_length=32)
Last_Name = models.CharField(max_length=32)
Date_Created = models.DateField(auto_now_add=True)
Creator = models.ForeignKey(User, on_delete=models.DO_NOTHING)
Approved = models.BooleanField(default=False)
Company_Relationship = (
('Supplier', 'Supplier'),
('Contractor', 'Contractor'),
('Employee', 'Employee')
)
Worker_Type = models.CharField(max_length=32, choices=Company_Relationship)
Total_Days_Worked = models.DecimalField(decimal_places=2, max_digits=3)
class Meta:
ordering = ['-id']
#unique_together = ['Creator', 'Work_Week']
def get_absolute_url(self):
return reverse('timesheet-detail', kwargs={'pk': self.pk})
class InternalSheet(models.Model):
id = models.CharField(primary_key=True, max_length=50, blank=True, unique=True, default=uuid.uuid4)
Timesheet_id = models.ForeignKey(Timesheet, on_delete=models.DO_NOTHING)
Working_For = (
('7', 'Seven'),
('i', 'intelligent'),
('S', 'Sata'),
)
iPSL = (
('R16.1', 'Release 16.1'),
('R16', 'Release 16')
)
Company_name = models.CharField(max_length=5, choices=Working_For)
Company_name_change = models.CharField(max_length=5, choices=Working_For)
Internal_Company_Role = models.CharField(max_length=10, choices=iPSL)
DaysWorked = models.DecimalField(decimal_places=2, max_digits=3)
Managers = (
('GW', 'Greg Wood'),
('JC', 'Jamie Carson')
)
ManagerName = models.CharField(max_length=8, choices=Managers)
Approved = models.BooleanField(default=False)
def get_absolute_url(self):
return reverse('sheet-detail', kwargs={'pk': self.pk})
My issue is that I am getting a foreign key failure using this post request.
class TimesheetCreateView(LoginRequiredMixin, CreateView):
"""
Creates view and send the POST request of the submission to the backend.
"""
def get(self, request, *args, **kwargs):
internal_form_loop = create_internal_form_for_context()
context = {'form': CreateTimesheetForm(), 'UserGroup': User()}
context.update(internal_form_loop)
print("new", context)
return render(request, 'create.html', context)
def post(self, request, *args, **kwargs):
form = CreateTimesheetForm(request.POST)
internal_form_1 = CreateInternalSheetForm(request.POST)
if form.is_valid():
print("forms valid")
external_timesheet = form.save(commit=False)
print("self", self.request.user)
print("id", Timesheet.id)
external_timesheet.Creator = self.request.user
external_timesheet.save()
else:
print("Error Here")
if internal_form_1.is_valid():
print("Internal form valid")
internal = internal_form_1.save(commit=False)
internal.Timesheet_id_id = Timesheet.id
internal.id = uuid.uuid4()
internal.save()
return HttpResponseRedirect(reverse_lazy('timesheet-detail', args=[Timesheet.id]))
return render(request, 'create.html', {'form': form, 'UserGroup': User()})
It is failing on the line internal.save(). If I print the line internal.Timesheet_id_id I get a value like this, <django.db.models.query_utils.DeferredAttribute object at 0x000001580FDB75E0>. I'm guessing this is the issue? I need the actual Foreign key and not the location of that object. How do I do this. Thanks.
Figured out the issue, I had to replace the lines
internal.Timesheet_id_id = Timesheet.id
internal.id = uuid.uuid4()
internal.save()
with
internal.Timesheet_id_id = Timesheet.objects.get(id=external_timesheet.id)
internal.save()
I want to test a form. It is working, but the test doesn't.
One field of this form is popolated by a javascript function. I can use selenium to do so, but I don't want because it's giving problems and also I want isolate the test.
So I'm calling the form in my test, then I'm creating the choices (this is what javascript should do), then I'm setting the fields values.
My models.py:
class Name(models.Model):
name = models.CharField(_('nome'), max_length=50, default='')
namelanguage = models.ForeignKey(
NameLanguage, related_name='%(app_label)s_%(class)s_language',
verbose_name=_('linguaggio'), on_delete=models.PROTECT)
nametype = models.ForeignKey(
NameType, related_name='%(app_label)s_%(class)s_tipo',
verbose_name=_('tipo'), on_delete=models.PROTECT)
gender = models.ForeignKey(
Gender, related_name='%(app_label)s_%(class)s_gender',
verbose_name=_('sesso'), on_delete=models.PROTECT,
blank=True, null=True)
usato = models.PositiveSmallIntegerField(_('usato'), default=0)
approved = models.BooleanField(null=True, blank=True, default=False)
def save(self, *args, **kwargs):
self.name = format_for_save_name(self.name)
to_save = check_gender_name(self)
if not to_save:
return
else:
super(Name, self).save(*args, **kwargs)
def format_for_save_name(name):
myname = name.lower().strip()
if myname[0] not in "abcdefghijklmnopqrstuvwxyz#":
myname = '#' + myname
return myname
My form.py:
class NameForm(forms.ModelForm):
class Meta:
model = Name
fields = ['namelanguage', 'nametype', 'gender', 'name', 'usato',
'approved']
widgets = {
'gender': forms.RadioSelect(),
'usato': forms.HiddenInput(),
'approved': forms.HiddenInput(),
}
My test_form.py:
def test_form_validation(self):
maschio = Gender.objects.create(name_en='Male', name_it='Maschio')
nome = NameType.objects.create(name_en='Name', name_it='Nome')
romani = NameLanguage.objects.create(
name_en='Romans', name_it='Romani')
romani.sintassi.add(nome)
form = NameForm()
form.fields['nametype'].disabled = False
form.fields['nametype'].choices = [(nome.id, nome)]
form.fields['nametype'].initial = nome.id
form.fields['gender'].initial = maschio.id
form.fields['name'].initial = 'Bill'
form.fields['namelanguage'].initial = romani.id
# form.fields['usato'].initial = 0
# form.fields['approved'].initial = False
print('1', form)
# self.assertTrue(form.is_valid())
form.save()
print('1', form) gives a form without errors but form.is_valid is False and (when is commented out) form.save() gives an error when the model try to save the name field:
if myname[0] not in "abcdefghijklmnopqrstuvwxyz#":
IndexError: string index out of range
That is because the name is an empty string and yet my print('1', form) gives all the fields with the right options selected and specifically the name field isn't empty but has value="Bill":
<td><input type="text" name="name" value="Bill" maxlength="50" autofocus="" required id="id_name">
Edit. I tried to avoid that check and the problem is the same for the other fields: they looks ok on the print('1', form) but they don't arrive to the form.save(), for example in my print('1', form) I have:
<tr><th><label for="id_namelanguage">Linguaggio:</label></th><td><select name="namelanguage" required id="id_namelanguage">
<option value="">---------</option>
<option value="1" selected>Romani</option>
so it looks I have selected an option but then I receive this error:
django.db.utils.IntegrityError: NOT NULL constraint failed: lists_name.namelanguage_id
I don't know why and how but this code is working:
def test_form_validation(self):
maschio = Gender.objects.create(name_en='Male', name_it='Maschio')
nome = NameType.objects.create(name_en='Name', name_it='Nome')
romani = NameLanguage.objects.create(
name_en='Romans', name_it='Romani')
romani.syntax.add(nome)
form = NameForm({'nametype': nome.id, 'gender': maschio.id,
'name': 'Remo', 'namelanguage': romani.id})
form.fields['nametype'].initial = nome.id
form.save()
self.assertEqual(Name.objects.all().count(), 1)
my_name = Name.objects.first()
self.assertEqual(my_name.name, 'remo')
self.assertEqual(my_name.nametype, nome)
self.assertEqual(my_name.gender, maschio)
self.assertEqual(my_name.namelanguage, romani)
Any comment will be appreciated
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
I have a PatientRegistrationForm and a PatientBillingForm form in a single view RegisterPatient.
When when I submit the patient form (form), the submitted date is stored in the database, nut the billing form (form1) only updates the staff and patient fields and nothing is stored in the payment_type, amount and receipt_number.
Please can anyone help point out why the second form is not being updated on the database?
Here is the views, models, forms and template code:
views.py
def RegisterPatient(request):
# bills = obj.bill_set.all()
form = PatientRegistrationForm(request.POST or None)
form1 = PatientBillingForm(request.POST or None)
if form.is_valid() and form1.is_valid():
instance = form.save(commit=False)
instance1 = form1.save(commit=False)
payment_type = form1.cleaned_data["payment_type"]
amount = form1.cleaned_data["amount"]
receipt_number = form1.cleaned_data["receipt_number"]
first_bill = Billing()
first_bill.payment_type = payment_type
first_bill.amount = amount
first_bill.receipt_number = receipt_number
# first_bill.saff
# first_bill.patients
print first_bill.payment_type, first_bill.amount, first_bill.receipt_number
first_name = form.cleaned_data["first_name"]
last_name = form.cleaned_data["last_name"]
other_name = form.cleaned_data["other_name"]
phone_number = form.cleaned_data["phone_number"]
new_patient = Patient()
new_patient.patient_number = UniquePatientNumber()
new_patient.first_name = first_name
new_patient.last_name = last_name
new_patient.other_name = other_name
new_patient.save()
first_bill.save()
model.py
class Patient(models.Model):
patient_number = models.CharField(max_length=120, unique = True, )
first_name = models.CharField(max_length = 120)
last_name = models.CharField(max_length=120)
other_name = models.CharField(max_length = 120, blank=True, null=True)
phone_number = models.CharField(max_length=15)
def _unicode_(self):
return self.patient_number
class Billing(models.Model):
staff = models.ForeignKey(MyUser, default=1)
patients = models.ForeignKey(Patient, default=1)
payment_type = models.CharField(max_length=100)
amount = models.DecimalField(max_digits=100, decimal_places=2, default=0.00)
receipt_number = models.CharField(max_length=120)
payment_date = models.DateTimeField(auto_now=False, auto_now_add=True)
def _unicode_(self):
return self.staff.username
def new_user_receiver(sender, instance, created, *args, **kwargs):
if created:
new_patient, is_created = Billing.objects.get_or_create(patients=instance)
post_save.connect(new_user_receiver, sender=Patient)
def new_user_creator(sender, instance, created, *args, **kwargs):
if created:
new_user, is_created = Billing.objects.get_or_create(staff=instance)
post_save.connect(new_user_creator, sender=MyUser)
form.py
class PatientRegistrationForm(forms.ModelForm):
class Meta:
model = Patient
exclude = ["patient_number"]
class PatientBillingForm(forms.ModelForm):
class Meta:
model = Billing
fields = ["payment_type","amount","receipt_number"]
forms.html
<form method="POST action="">{% csrf_token %}
{{ form }}
{{ form1 }}
<input type="submit" value="Submit"/>
</form>
In your view function you always create new Billing to MyUser with pk=1 and Patients with pk=1 because you set the default values in Billing fields default=1. You should remove default=1 and set null=True,blank=True instead.
If I understand your logic. You want to create new Billing information to every new User oder new Patient. I guess that in your view function you want to update or create Billing information to a patient. If so you should call
Billing.objects.filter(patients__pk=new_patient.pk).update(payment_type=payment_type,amount=amount,receipt_number=receipt_number)
after new_patient.save() then you could comment out lines with first_bill.
Update
1) comment out the line Billing.objects.filter(...)
2) comment out post_save.connect(new_user_receiver, sender=Patient) in models.py
3) activate the lines with first_bill again and add:
first_bill.patients=new_patient after new_patient.save()
I have a view that uses a modelform to create circles. This works perfectly fine on localhost but on server, the data is not getting created since "save" method is not working.
ModelForm:
class CircleForm(forms.ModelForm):
class Meta:
model = Circles
fields = ('heading','description',)
#exclude = ['current_status', 'progress', 'Owner', 'team_tag', 'exceptional_tag','Team']
def __init__(self, *args, **kwargs):
super(CircleForm, self).__init__(*args, **kwargs)
for name, field in self.fields.items():
if field.widget.attrs.has_key('class'):
field.widget.attrs['class'] += ' text'
else:
field.widget.attrs.update({'class':'text'})
Model:
class Circles(CommonInfo):
CURRENT_STATUS = (('P', 'pending'),
('C', 'complete'),
('ED', 'exceeded deadline'),
('I', 'incomplete'))
Owner = models.ForeignKey(OrganisationUser, related_name="owner_name", blank=True, null=True)
Team = models.TextField(default='', blank=True, null=True)
heading = models.CharField(default='', max_length=100)
description = models.CharField(default='', max_length=250)
progress = models.PositiveIntegerField(default=0, null=True, blank=True)
deadline = models.DateField(null=True,blank=True)
current_status = models.CharField(choices=CURRENT_STATUS, max_length=2, default='P')
team_tag = models.ForeignKey("certificates.Tag", related_name="team_tag_given", blank=True, null=True)
exceptional_tag = models.ForeignKey("certificates.Tag", related_name="exeptioml_tag_given", blank=True, null= True)
View:
def non_ajax_post(self, request, *args, **kwargs):
circle_form = CircleForm(request.POST)
if circle_form.is_valid():
try:
circle = circle_form.save(commit=False)
circle.Owner = request.user.organisation_user
#circle.Team = json.dumps(request.POST.get('hidemps_id'))
team_tag = Tag.objects.get(pk = request.POST.get('team_tag_id'))
exceptional_tag = Tag.objects.get(pk = request.POST.get('exceptional_tag_id'))
circle.team_tag = team_tag
circle.exceptional_tag = exceptional_tag
deadline = string_time_to_datetime(request.POST.get('deadline'), type_of_date='m/d/y')
if deadline < datetime.now():
request.session['deadline_error'] = True
return HttpResponseRedirect(request.path)
circle.deadline = deadline
circle.save()
request.session['circle_saved'] = True
return HttpResponseRedirect(request.path) #here a different context is sent on page load
except Exception as e:
print e.message
else:
return HttpResponseRedirect(request.path)
return HttpResponseRedirect(request.path)
This code works the way I want it and creates a circle. But this happens when I perform this on localhost. When I try it on the server, it doesn't work.
The problem lies in the line "circle.save()"
I used multiple print statements to find out the problem. The printing stops when it encounters "circle.save()" line. After that it redirects me to the same page.
Can anyone suggest some solutions?