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.
Related
Model.py
class Branch(models.Model): # Branch Master
status_type = (
("a",'Active'),
("d",'Deactive'),
)
name = models.CharField(max_length=100, unique=True)
suffix = models.CharField(max_length=8, unique=True)
Remark = models.CharField(max_length=200, null=True, blank=True)
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=1, choices = status_type, default = 'a')
def __str__(self):
return self.name
class Vendor(models.Model):
status_type = (
("a",'Active'),
("d",'Deactive'),
)
branch = models.ManyToManyField(Branch)
company = models.CharField(max_length=200)
name = models.CharField(max_length=200)
phone = models.CharField(max_length=11, unique = True)
email = models.EmailField(max_length=254, unique = True)
gst = models.CharField(max_length=15, unique = True)
pan_no = models.CharField(max_length=10, unique = True)
add_1 = models.CharField(max_length=50, null=True, blank = True)
add_2 = models.CharField(max_length=50, null=True, blank = True)
add_3 = models.CharField(max_length=50, null=True, blank = True)
Remark = models.CharField(max_length=200, null=True, blank=True)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=1, choices = status_type, default = 'a')
def __str__(self):
return self.company
form.py
i want save like created_by field
class VendorForm(ModelForm):
class Meta:
model = Vendor
fields = 'all'
exclude = ['created_by', 'branch']
widgets = {
'company':forms.TextInput(attrs={'class':'form-control'}),
'name':forms.TextInput(attrs={'class':'form-control'}),
'phone':forms.TextInput(attrs={'class':'form-control'}),
'email':forms.EmailInput(attrs={'class':'form-control'}),
'gst':forms.TextInput(attrs={'class':'form-control'}),
'pan_no':forms.TextInput(attrs={'class':'form-control'}),
'add_1':forms.TextInput(attrs={'class':'form-control'}),
'add_2':forms.TextInput(attrs={'class':'form-control'}),
'add_3':forms.TextInput(attrs={'class':'form-control'}),
'Remark':forms.Textarea(attrs={'class':'form-control','rows':'2'}),
'status':forms.Select(attrs={'class':'form-control'}),
}
Views.py
I have pass branch in session.
I want to save with branch which is many to many field
def Add_Vendor(request): # for vendor add
msg = ""
msg_type = ""
branch_id = request.session['branch_id']
branch_data = Branch.objects.get(id = branch_id)
form = ""
if request.method == "POST":
try:
form = VendorForm(request.POST)
if form.is_valid:
vendor_add = form.save(commit=False)
vendor_add.created_by = request.user
vendor_add.instance.branch = branch_data.id
vendor_add.save()
form.save_m2m() # for m to m field save
msg_type = "success"
msg = "Vendor Added."
form = VendorForm(initial={'branch':branch_id})
except:
msg_type = "error"
msg = str(form.errors)
print(msg)
else:
form = VendorForm(initial={'branch':branch_id})
context = {
'form':form,
'branch_data':branch_data,
'msg_type':msg_type,
'msg':msg,
'btn_type':'fa fa-regular fa-plus',
'form_title':'Vendor Form',
'tree_main_title':'Vendor',
'v_url':'vendor_page',
'tree_title':'Add Form',
}
return render(request, 'base/vendor_master/form_vendor.html',context)
I would advise not to work with commit=False in the first place:
def Add_Vendor(request): # for vendor add
branch_id = request.session['branch_id']
branch_data = get_object_or_404(Branch, pk=branch_id)
if request.method == 'POST':
form = VendorForm(request.POST, request.FILES)
if form.is_valid():
form.instance.created_by = request.user
form.instance.branch = branch_data.id
vendor_add = form.save()
vendor_add.branch.add(branch_data)
return redirect('name-of-some-view')
else:
form = VendorForm()
context = {
'form': form,
'branch_data': branch_data,
'btn_type': 'fa fa-regular fa-plus',
'form_title': 'Vendor Form',
'tree_main_title': 'Vendor',
'v_url': 'vendor_page',
'tree_title': 'Add Form',
}
return render(request, 'base/vendor_master/form_vendor.html', context)
You can simplify your form by automatically adding form-control to each widget:
class VendorForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
attrs = field.widget.attrs
attrs['class'] = attrs.get('class', '') + ' form-control'
class Meta:
model = Vendor
exclude = ['created_by', 'branch']
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
Note: You can set a field editable=False [Django-doc]. Then the field does not show up in the ModelForms and ModelAdmins by default. In this case for example with created_by.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Note: Please do not pass messages manually to the template. Django has the messages framework [Django-doc], which allows to add messages to the request, which will then be delivered the next time a template renders these messages. This makes delivering multiple messages convenient, as well as setting different log levels to the messages.
I have a form that users can fill to leave a review. On the same page, the reviews are displayed with a button to edit the review. When the edit button is clicked, I would like for the form to be pre-filled with the appropriate review data, so that it can be edited and updated in the database.
models
class Clinic(models.Model):
practitioner = models.OneToOneField(User, on_delete=models.CASCADE)
lat = models.FloatField(null=True, blank=True)
lng = models.FloatField(null=True, blank=True)
web = models.CharField(null=True, blank=True, max_length=128)
name = models.CharField(max_length=128, )
phone = PhoneNumberField()
description = models.TextField(max_length=5000)
street = models.CharField(max_length=128, )
city = models.CharField(max_length=128, )
def __str__(self):
return self.name
def save(self):
super().save()
class Reviews(models.Model):
title = models.CharField(max_length=128)
body = models.TextField(max_length=500)
author = models.ForeignKey(User, on_delete=models.CASCADE)
clinic = models.ForeignKey(Clinic,
null=True,
blank=True,
on_delete=models.CASCADE)
Form
class ReviewForm(forms.ModelForm):
class Meta:
model = Reviews
fields = (
'title',
'body',
)
View
def clinic_profile(request, clinic_id):
clinic = Clinic.objects.filter(pk=clinic_id)
form = ReviewForm(request.POST)
if request.method == 'POST':
if form.is_valid():
r_clinic = Clinic.objects.get(pk=clinic_id)
title = form.cleaned_data.get("title")
body = form.cleaned_data.get("body")
review = Reviews(title=title,
body=body,
author=request.user,
clinic=r_clinic)
review.save()
messages.success(request, f'Thank you for leaving a review!')
clinic_reviews = Reviews.objects.filter(clinic=clinic_id)
latlng = {
"lat": clinic[0].lat,
"lng": clinic[0].lng,
"name": clinic[0].name
}
def get_mods():
profile = Profile.objects.filter(user=Clinic.objects.get(
pk=clinic_id).practitioner)
mods = profile[0].mods.all().values('name') if profile else []
mods = [(q['name']) for q in mods]
return mods
return render(
request, 'clinic_profile.html', {
'clinic': clinic,
'mods': get_mods,
'latlng': latlng,
'api_key': api_key,
'reviews': clinic_reviews,
'form': form,
})
Screenshot
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)
Good days guys need help for my ForeignKey Relationship in my models,
i want my foreignkey values is equal to the user choose
Here's my model view
class ProjectNameInviToBid(models.Model):
ProjectName = models.CharField(max_length=255, verbose_name='Project Name', null=True)
DateCreated = models.DateField(auto_now=True)
def __str__(self):
return self.ProjectName
have relations to ProjectNameInviToBid
class InviToBid(models.Model):
today = date.today()
ProjectName = models.ForeignKey('ProjectNameInviToBid', on_delete=models.CASCADE, null=True)
NameOfFile = models.CharField(max_length=255, verbose_name='Name of File')
Contract_No = models.IntegerField(verbose_name='Contract No')
Bid_Opening = models.CharField(max_length=255, verbose_name='Bid Opening')
Pre_Bid_Conference = models.CharField(max_length=255, verbose_name='Pre Bid Conference')
Non_Refundable_Bidder_Fee = models.CharField(max_length=255, verbose_name='Non Refundable Fee')
Delivery_Period = models.CharField(max_length=255, verbose_name='Delivery Period')
Pdf_fileinvi = models.FileField(max_length=255, upload_to='upload/invitoBid', verbose_name='Upload Pdf File Here')
Date_Upload = models.DateField(auto_now=True)
This is my form view
class invitoBidForm(ModelForm):
class Meta:
model = InviToBid
fields = ('ProjectName','NameOfFile', 'Contract_No', 'Bid_Opening',
'Pre_Bid_Conference', 'Non_Refundable_Bidder_Fee',
'Delivery_Period',
'Pdf_fileinvi')
and Lastly this my view Forms
def project_name_details(request, sid):
majordetails = ProjectNameInviToBid.objects.get(id=sid)
if request.method == 'POST':
form = invitoBidForm(request.POST, request.FILES)
if form.is_valid():
majordetails = form.ProjectName
form.save()
messages.success(request, 'File has been Uploaded')
else:
form = invitoBidForm()
args = {
'majordetails': majordetails,
'form': form
}
return render(request,'content/invitoBid/bacadmininvitoBid.html', args)
but im have a error,, hope you can help me. thank you in advance
I want to set the form value..i am not displaying it in form but want to set the value of field in my view?
This my modelform:
class payment_detail(models.Model):
status = (
('Paid','Paid'),
('Pending','Pending'),
)
id = models.AutoField(primary_key=True)
#ref_id = models.CharField(max_length=32, default=_createId)
#user = models.ForeignKey(User, editable = False)
payment_type= models.ForeignKey(Payment_types,to_field = 'payment_types', null=True, blank=True)
job_post_id= models.ForeignKey(jobpost,to_field = 'job_id', null=True, blank=True)
price= models.ForeignKey(package,to_field = 'amount', null=True, blank=True)
created_date = models.DateField(("date"), default=datetime.date.today)
payment_status = models.CharField(max_length=255, choices=status,default='Pending')
transaction_id = models.CharField(max_length=255, null=True, blank=True)
payment_date = models.DateField(null=True, blank=True)
email = models.CharField(max_length=255, null=True)
def __unicode__(self):
#return self.user
return unicode(self.id)
#return self.ref_id
return unicode(self.payment_type)
return unicode(self.job_post_id)
return unicode(self.price)
return unicode(self.created_date)
return unicode(self.payment_status)
return unicode(self.payment_date)
return unicode(self.transaction_id)
return unicode(self.email)
admin.site.register(payment_detail)
my View:
def payment(request):
if "pk" in request.session:
pk = request.session["pk"]
Country = request.session["country"]
price = package.objects.filter(item_type__exact='Job' ,country__country_name__exact=Country, number_of_items__exact='1')
if request.method == 'POST':
entity = payment_detail()
form = jobpostForm_detail(request.POST, instance=entity)
if form.is_valid():
#form.fields["transaction_id"] = 100
form.save()
#message = EmailMessage('portal/pay_email.html', 'Madeeha ', to=[form.cleaned_data['email']])
#message.send()
return HttpResponseRedirect('/portal/pay/mail/')
else:
form = jobpostForm_detail(initial={'transaction_id': "US"})
c = {}
c.update(csrf(request))
return render_to_response('portal/display.html',{
'form':form,'price':price
},context_instance=RequestContext(request))
like i want to set the value of job_location and don't want to display it in form..
forms.py
//this is how you hide the field
class jobpostForm(ModelForm):
def __init__(self, *args, **kwargs):
super(jobpostForm, self).__init__(*args, **kwargs)
self.fields['job_location'].widget = forms.HiddenInput()
class Meta:
model = jobpost
views.py
.........
if request.method == 'POST':
entity = payment_detail(transaction_id="US") #change
form = jobpostForm_detail(request.POST, instance=entity)
if form.is_valid():
#form.fields["transaction_id"] = 100
form.save()
#message = EmailMessage('portal/pay_email.html', 'Madeeha ', to=[form.cleaned_data['email']])
#message.send()
return HttpResponseRedirect('/portal/pay/mail/')
else:
form = jobpostForm_detail()
..................