Reputation: 401
I have a model:
class Order(models.Model):
order_type = models.ForeignKey(OrderType)
quantity = models.IntegerField(max_digits=10, decimal_places=4)
product = models.ForeignKey(Product)
I added the form filed dynamically:
class OrderForm(ModelForm):
class Meta:
model = Order
fields = [
'order_type', 'product'
]
widgets = {
'order_type': Select(attrs={'class': 'form-control'}),
'product': Select(attrs={'class': 'form-control'}),
}
def __init__(self, types=[],*args, **kwargs):
super(OrderForm, self).__init__(*args, **kwargs)
if "AMOUNT" in types:
self.fields['quantity'] = IntegerField(
NumberInput(attrs={'class': 'form-control'})
)
And in CreateView
I overwrite post. In the frontend I'm sending ajax with data or not (if data is sent, I want to generate form with addition quantity field), then I replace the old form with this new:
class OrderCreateView(CreateView):
model = Order
form_class = OrderForm
def post(self, request, *args, **kwargs):
self.object = None
d = request.POST.get('DATA', None)
if d is not None:
form = self.form_class(
types=["AMOUNT"],
**self.kwargs
)
return render(
request, 'form.html', {'form': form}
)
else:
form = self.form_class(**self.kwargs)
return render(
request, 'form.html', {'form': form}
)
return super(OrderCreateView, self).post(request, *args, **kwargs)
And it "works". I get new form with a quantity. But when I'm trying do submit this form, I get an error
null value in column "quantity" violates not-null constraint
Upvotes: 0
Views: 387
Reputation: 47364
Last line of your post method is unreachable. Post function will never go here:
return super(OrderCreateView, self).post(request, *args, **kwargs)
I suppose you need to change logic of your code. For example if it possible instead of sending 'DATA' with POST try to send it with GET. Or create another view to render form with 'AMOUNT' field.
UPDATE
Also please note that super().post()
calls get_form() which return default instance of form_class. Considering this super().post()
probably is not what you really need. Try to perform form validation and form saving manually:
form = self.form_class(
types=["AMOUNT"],
**self.kwargs
)
if form.is_valid():
instance = self.form.save()
return super().get()
Upvotes: 1
Reputation: 2827
In your model try to change
quantity = models.IntegerField(max_digits=10, decimal_places=4)
to
quantity = models.IntegerField(max_digits=10, decimal_places=4, null=True, blank=True)
Whenever you don't have the flag "AMOUNT" it tries to create an Order without filling that field.
UPDATE: Try this in your form
fields = [
'order_type', 'product', 'quantity'
]
widgets = {
'order_type': Select(attrs={'class': 'form-control'}),
'product': Select(attrs={'class': 'form-control'}),
'quantity': NumberInput(attrs={'class': 'form-control'}),
}
def __init__(self, types=[],*args, **kwargs):
super(OrderForm, self).__init__(*args, **kwargs)
if "AMOUNT" not in types:
del self.fields['quantity']
In your view put the super()
before as @neverwalkaloner mentioned
Upvotes: 1