简体   繁体   中英

How to customize a ModelForm with ChoiceField for a Model FloatField attribute Django

I have a model called Invoice with the following attribute (and other stuff):

class Invoice(models.Model):
    tax = models.FloatField()

And a model called Tax:

class Tax(models.Model):
    name = models.CharField(max_length=20)
    value = models.FloatField()
    creation_date = models.DateTimeField(auto_now_add=True)
    description = models.CharField(max_length=50, blank=True)

    def __unicode__(entry):
        return str(entry.id) + " - " + entry.name + " (%.1f" % (entry.value) + "%)"

On my ModelForm I have:

class InvoiceForm(ModelForm):
    class Meta:
        model = Invoice
        fields = '__all__'
        widgets = {
            'due_date': forms.TextInput(attrs={'class': 'form-control'}),
            'due_date': DateTimePicker(options={"format": "DD/MM/YYYY","pickTime": False}),
            'tax': forms.ChoiceField(choices=(Tax))
    }

What I want is to generate a ModelForm for this class replacing the FloatField for a ChoiceField with the values from the class Tax. And when the form is submitted I would get the value of the tax (tax.value) and set to invoice.tax, since both are the same data type.

I was expecting to do something like when we have a M2M relation, that you have the dropbox. The problem in my project is that if the value of the Tax is modified or even deleted, I will have problems with my already generated invoices.

I could do some workaround and make it work when the page is submitted, but I don't want to do that. This is my first project with Django and I would like to learn all its potential.

You might not need a ModelForm but a normal Form because what you get from the InvoiceForm is a Tax object, which doesn't fit in your Invoice model.

What you can do is define a form with every field except tax for Invoice , then for the tax field you use form.ModelChoiceField :

class InvoiceForm(Form):
    # define all your fields, I put some dummy fields here
    field1 = CharField()
    field2 = TextField()
    # etc
    tax = ModelChoiceField(queryset=Tax.objects.all())

Then in your views.py, get the values manually and construct your Invoice :

form = InvoiceForm(request.POST)
if form.is_valid():
    field1 = form.cleaned_data['field1']
    field2 = form.cleaned_data['field2']
    tax_obj = form.cleaned_data['tax']
    # create your invoice here
    new_invoice = Invoice.objects.create(field1=field1,
                                         field2 = field2,
                                         tax=tax_obj.value)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM