Search code examples
django-formsdjango-templatesdjango-2.0

How can I pass unique id fields from a Model to a Django form when looping through model in a template?


I need to create unique id for each form that is generated from a loop in Django templates. I use {% for product in products %} to loop through some data. In my forms.py I edit the form.widget.Select attributes to add/change the onchange and id fields. I render it through views.py and my templates as {{form}}, Here is the line in forms.py:

condition = forms.ChoiceField(choices=condition_choices, widget=forms.Select(attrs={'onchange' : "showChange(this)", "id":"{{product.id}}"}))

I expected the id to render as a unique id associated with each product, and I expected the onchange to call a js function. When I print the form to the console, it looks like this:

<select name="condition" onchange="showChange(this)" id="{{product.id}}">
  <option value="NM / LP">Near Mint / Lightly Played</option>

  <option value="MP">Moderately Played</option>

  <option value="HP">Heavily Played</option>

  <option value="Damaged">Damaged</option>

  <option value="Unopened">Unopened</option>

</select>

I would expect the id field to be the actual id and not {{product.id}} If this form is pasted exactly into html without rendering it as a Django form, it works as expected. How can I pass my product's unique id to Django forms without importing the Database into forms.py/extra Database calls?


Solution

  • You cannot use {{product.id}} in .py files. It's a Django template engine tag.

    In your views.py you should create your form like this:

    product = Product.objects.get(pk=1)
    
    form = ProductForm(instance=product)
    
    context = {
        'form': form
    }
    

    when you pass the form then you can use it's data in the __init__ method.

    and your form will look like this

    class ProductForm(forms.ModelForm):
    
    class Meta:
        model = Product
        exclude = ()
    
    def __init__(self, *args, **kwargs):
        super(ProductForm, self).__init__(*args, **kwargs)
        instance = kwargs['instance']
        self.fields['condition'].widget.attrs['id'] = instance.id