I'm building a small web service for inventory control. As part of this, I want to populate a detail view for any of the inventory items. This is what I have so far for that:
class Product_Update(forms.Form):
Product_Code = forms.CharField(
max_length=10,
attrs={"placeholder = <ID here> Readonly = True"
)
Name = forms.CharField(max_length=100)
Description = forms.Textarea(attrs={"Rows": 3})
price = forms.DecimalField()
mini = forms.IntegerField()
Max = forms.IntegerField()
How do I pass the form the parameters?
You should use a ModelForm instead:
class ProductUpdate(forms.Form):
class Meta:
model = Product
fields = ('product_code', 'name', 'description', 'price', 'mini', 'max')
Now you can easily pass a model instance to your form:
def some_view(request):
instance = Product.objects.first()
form = ProductUpdate(request.POST or None, instance=instance)
context = {'form':form}
return render(request, 'some_template.html', context)
If you want to show multiple products in the same form, you will need to use modelformset_factory:
from django import forms
ProductFormSet = forms.modelformset_factory(Product, form=ProductUpdate, extra=0)
Now in your views.py, you can pass a QuerySet to your form:
def some_view(request):
queryset = Product.objects.all()
form = ProductFormSet(request.POST or None, queryset=queryset)
if request.method == 'POST' and form.is_valid():
form.save()
context = {'form':form}
return render(request, 'some_template.html', context)
You can access the form's data in the view by accessing request.POST
def actionView(request, product_id):
product = Product.objects.get(id=product_id)
form = ProductUpdate(request.POST, instance=product_id)
form.save(commit=False) #Do this if you want to make changes to some value
form.price = 112233
updated_form = form.save()
Related
I would like to start using an abstract model for my application (based on a django-accounting app). How should I create my field on the views.py. I guess I will also need to change my view file when creating a new field...Can I still create the same way I used to if it was not an abstract model?
views.py
#login_required(login_url="/login/")
def create_bill(request):
form = BillForm(request.POST or None, request.FILES or None)
if form.is_valid():
bill = form.save(commit=False)
bill.save()
return render(request, 'accounting/bills/detail.html', {'bill': bill})
context = {
"form": form,
}
return render(request, 'accounting/bills/create_bill.html', context)
#login_required(login_url="/login/")
def detail_bill(request, bill_id):
user = request.user
bill = get_object_or_404(Bill, pk=bill_id)
return render(request, 'accounting/bills/detail.html', {'bill': bill, 'user': user})
#login_required(login_url="/login/")
def bill_update(request, bill_id):
bill = get_object_or_404(Bill, pk=bill_id)
form = BillForm(request.POST or None, instance=bill)
if form.is_valid():
form.save()
return render(request, 'accounting/bills/index_table.html', {'bill': bill})
else:
form = BillForm(instance=bill)
return render(request, 'accounting/bills/edit.html', {'form': form})
models.py
class AbstractSale(CheckingModelMixin, models.Model):
number = models.IntegerField(default=1,db_index=True)
# Total price needs to be stored with and wihtout taxes
# because the tax percentage can vary depending on the associated lines
total_incl_tax = models.DecimalField("Total (inc. tax)",decimal_places=2,max_digits=12,default=D('0'))
total_excl_tax = models.DecimalField("Total (excl. tax)",decimal_places=2,max_digits=12,default=D('0'))
# tracking
date_issued = models.DateField(default=date.today)
date_dued = models.DateField("Due date",blank=True, null=True,help_text="The date when the total amount ""should have been collected")
date_paid = models.DateField(blank=True, null=True)
class AbstractSaleLine(models.Model):
label = models.CharField(max_length=255)
description = models.TextField(blank=True, null=True)
unit_price_excl_tax = models.DecimalField(max_digits=8,decimal_places=2)
quantity = models.DecimalField(max_digits=8,decimal_places=2,default=1)
class Meta:
abstract = True
class Bill(AbstractSale):
organization = models.ForeignKey('Organization',on_delete=models.CASCADE, related_name="bills", verbose_name="To Organization")
client = models.ForeignKey('contacts.Client', on_delete=models.CASCADE,verbose_name="From client")
payments = GenericRelation('Payment')
class BillLine(AbstractSaleLine):
bill = models.ForeignKey('Bill',related_name="lines",on_delete=models.CASCADE)
tax_rate = models.ForeignKey('TaxRate',on_delete=models.CASCADE)
class Meta:
pass
if you use class-based-views (CBV) you can use inheritance as found in pure python.
Note that you have not defined a Meta class (and with abstract=True) within your AbstractSale class. By not doing this, you will end up with an additional table in your database. For more info see here.
I want to set a default value in a form and it will be reset as approval = False in every update. I tried something but it did not work it doesn't change. How can I fixed it?
forms.py
class UpdateDoaTableForm(forms.ModelForm):
approval = forms.BooleanField(required=False,
initial=False,
label='Approved',
widget=forms.HiddenInput()
)
class Meta:
model = DoaTable
fields = ('limit', 'approval')
views.py
def update_limit(request, id):
limiting = get_object_or_404(DoaTable, id=id)
form = UpdateDoaTableForm(request.POST or None, request.FILES or None, instance=limiting)
limiting_item = DoaTable.objects.filter(id=id)
if form.is_valid():
form.save()
return redirect('approvals:update_limit_list')
context = {
'form': form,
'limiting_item': limiting_item,
}
return render(request, 'limitUpdate.html', context)
models.py
class DoaTable(models.Model):
...
approval = models.BooleanField(default=False)
I edit my code and it is working now.:
views.py
if form.is_valid():
update_form = form.save(commit=False)
update_form.approval = False
update_form.save()
return redirect('approvals:update_limit_list')
I am trying to filter some choices by Djangos stock Groups, but when I do so in web form is empty.
If I put Group number directly when filtering, it works. Maybe I have something wrong with arguments?
in views.py I have:
class AddSupplier(generic.View):
form_class = CreateOrder
template_name = 'order/order_form.html'
#blank, ce je get metoda
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
group = self.request.user.groups.values_list('id', flat=True).first()
# I tried:
# group = self.request.user.groups.all()
# same result
form = self.form_class(group, request.POST)
if form.is_valid():
createS = form.save(commit=False)
supplier = form.cleaned_data['supplier']
createS.save()
return render(request, self.template_name, {'form': form})
forms.py
class CreateOrder(forms.ModelForm):
def __init__(self, group,*args,**kwargs):
super (CreateOrder, self ).__init__(*args,**kwargs)
self.fields['supplier'].queryset = Supplier.objects.filter(group_s=group) # if I put group = 1 it works
class Meta:
model = Order
fields = [
'supplier',
]
and how thinks are connected in models.py:
class Supplier(models.Model):
#...
group_s = models.ManyToManyField(Group, help_text="kateri dobavitelji imajo katere stranke")
#...
class Order(models.Model):
#...
supplier = models.ForeignKey(Supplier, on_delete=models.SET_NULL, null=True)
#...
You are not currently including the group when you instantiate the form for get requests. Try changing the code to:
def get(self, request):
group = self.request.user.groups.values_list('id', flat=True).first()
form = self.form_class(group, None)
return render(request, self.template_name, {'form': form})
I'm doing a multi step form where everything is saved at the end. In my models I have a m2m checkbox field and I'm using django Sessions to grab the forms datas to show it on the final step.
The issue is that the m2m field (checkboxes) is not saved when I submit the final form.
Here is my views file :
views.py
def step1(request):
initial={'name': request.session.get('name', None), 'checkbox': request.session.get('checkbox', (False,))} #cookies
form = FormOneForm(request.POST or None, initial=initial)
if request.method == 'POST':
if form.is_valid():
request.session['name'] = form.cleaned_data['name']
request.session['checkbox'] = form.cleaned_data.get('checkbox')
return HttpResponseRedirect(reverse('step2'))
return render(request, 'step1.html', {'form': form})
def step2(request):
form = FormTwoForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
formtwo = form.save(commit=False)
formone2 = FormOne.objects.create(checkbox=request.session.get('checkbox')) #error is here
formone = FormOne.objects.create(name=request.session['name'])
formtwo.owner = formone
formtwo.save()
formone2.save_m2m()
return HttpResponseRedirect(reverse('step3'))
return render(request, 'step2.html', {'form': form})
models.py
class Font(models.Model):
font_name = models.CharField(max_length=100)
font_family = models.CharField(max_length=100)
font_link = models.CharField(max_length=100)
...
class FormOne(models.Model):
name = models.CharField(max_length=40)
checkbox = models.ManyToManyField(Font, blank=True)
...
class FormTwo(models.Model):
owner = models.ForeignKey(FormOne)
name = models.CharField(max_length=40)
...
this code gives me this error :
'checkbox' is an invalid keyword argument for this function
How can I achieve what I am trying to realise ?
Try to save object first:
formone2 = FormOne.objects.create(name=request.session['name'])
formone2.checkbox.add(request.session.get('checkbox')
The problem is that you need to save object before use Many-to-many relations. See docs:
You can’t associate it with a Publication until it’s been saved
I want to pass a pk from one form to another so that it can be used as the foreign key for the second form. Here are the model:
models.py
class CompanyDetails(models.Model):
name = models.CharField(max_length=100)
class CompanyDetailsForm(forms.ModelForm):
class Meta:
model = CompanyDetails
class DataRequest(models.Model):
company = models.ForeignKey(CompanyDetails, default="0")
agency_name = models.CharField(max_length=100)
class DataRequestForm(forms.ModelForm):
class Meta:
model = DataRequest
exclude = ['company']
And here is the view for the first form:
views.py
def index(request):
if request.method == 'POST':
form = CompanyDetailsForm(request.POST or None)
if form.is_valid():
data = form.save(commit=False)
data.save()
return HttpResponseRedirect(reverse('canareeform:datarequest', data.id))
else:
form = CompanyDetailsForm()
return render(request, 'canareeform/index.html', {'form': form})
How should I set up my second view so that the form will save an object that has the foreign key for the object created by the first form in it?
I got it to work by passing the primary key of the first object through the url. It goes abc.com/form -> abc.com/form/16/datarequest. Not super ideal since by changing the number in the url the second object will use some other foreign key.
views.py
def index(request):
if request.method == 'POST':
form = CompanyDetailsForm(request.POST or None)
if form.is_valid():
data = form.save(commit=False)
data.save()
return HttpResponseRedirect(reverse('canareeform:datarequest', args=(data.id,)))
else:
form = CompanyDetailsForm()
return render(request, 'canareeform/index.html', {'form': form})
def datarequest(request, company_id):
if request.method == 'POST':
form = DataRequestForm(request.POST or None)
if form.is_valid():
data = form.save(commit=False)
data.company = CompanyDetails.objects.get(pk=company_id)
data.save()
return HttpResponse("Thanks")
else:
form = DataRequestForm()
return render(request, 'canareeform/datarequest.html', {'form': form})
If anyone has a better solution I'd love to hear it.