Search code examples
djangoformsfor-loopinputformfield

Django form with inputs populated from database


I have a simple Django model structure with Products and Orders, linked by an intermediary table that determines the quantity of each product within a given order:

models.py:

class Product(models.Model):
    name = models.CharField()

class Order(models.Model):
    id = models.IntegerField()
    products = models.ManyToManyField(Product, through='OrderProduct')

class OrderProduct(models.Model):
    order=models.ForeignKey(Order, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveSmallIntegerField()

I'd like to design a form in my forms.py file that 1) pulls a list of every product in the database; 2) gives the user the option to adjust the quantity of each product ordered (e.g., in a CharField input), and 3) creates new Order and OrderProduct objects that store a record of the quantity of each Product ordered by the user.

However, I can't figure out a good way to create a form that will automatically pull all Products from the database and add fields to represent the quantity ordered of the given Product. Ideally the result would look something like this, but coded automatically:

forms.py:

class OrderForm(forms.Form):
    product_1_quantity = forms.IntegerField()
    product_2_quantity = forms.IntegerField()
    product_3_quantity = forms.IntegerField()

....etc., for each product. What's the best way to do this? Does it involve a 'for' loop that creates a new field for each product found in the database?


Solution

  • I think Django Formsets might be useful for you. You can create sets of the same form over and over depending based on number you decide, hence your products. Check it out here . You can do stuff such as in the below example.

    class ArticleForm(forms.Form):
       title = forms.CharField()
    
    from django.forms import formset_factory
    ArticleFormSet = formset_factory(ArticleForm, extra=2)
    

    You can also pre-populate it with data such as,

    formset = ArticleFormSet(initial=[
          {'title': 'Django is now open source'}
       ])
    

    Hope this helps!