Last active
December 16, 2015 16:52
-
-
Save rahit/946e1c076dac9269552f to your computer and use it in GitHub Desktop.
Dynamic form field based on another model's entries and save them in a m2m way in Django
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from myapp.models import Attribute, Item, ItemAttribute | |
from django.forms import ModelForm, HiddenInput, IntegerField, CharField | |
class ItemForm(ModelForm): | |
class Meta(): | |
model = Item | |
exclude = ['attributes'] | |
def __init__(self, *args, **kwargs): | |
self.request = kwargs.pop('request') | |
super(ItemForm, self).__init__(*args, **kwargs); | |
# Getting all attributes | |
attributes = Attribute.objects.all() | |
# Dynamically adding form field for each attribute | |
for attr in attributes: | |
# hardcodingly using char field type. | |
# In future it will be dynamicly handled by the type | |
# specified in attribute_type | |
self.fields[attr.attribute] = CharField(required=True) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import unicode_literals | |
from django.db import models | |
class Attribute(models.Model): | |
TYPE_CHOICES = ( | |
('text', 'text'), | |
('number', 'number') | |
) | |
attribute = models.CharField(primary_key=True, max_length=50) | |
attribute_type = models.CharField(max_length=20, choices=TYPE_CHOICES) | |
def __str__(self): # __unicode__ on Python 2 | |
return self.attribute | |
class Item(models.Model): | |
id = models.AutoField(primary_key=True) | |
name = models.CharField(max_length=50) | |
attributes = models.ManyToManyField(Attribute, through='ItemAttribute') | |
def __str__(self): # __unicode__ on Python 2 | |
return self.id | |
class ItemAttribute(models.Model): | |
id = models.AutoField(primary_key=True) | |
item = models.ForeignKey(Item, on_delete=models.CASCADE) | |
attribute = models.ForeignKey(Attribute, on_delete=models.CASCADE) | |
value = models.CharField(max_length=250) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.core.urlresolvers import reverse_lazy | |
from myapp.forms import ItemForm | |
from myapp.models import Item, ItemAttribute, Attribute | |
class ItemCreate(FormView): | |
form_class = ItemForm | |
template_name = 'myapp/item_form.html' | |
success_url = reverse_lazy('item_list') | |
# add the request to the kwargs | |
def get_form_kwargs(self): | |
kwargs = super(ItemCreate, self).get_form_kwargs() | |
kwargs['request'] = self.request | |
return kwargs | |
def form_valid(self, form): | |
item = form.save(commit = True) | |
attributes = Attribute.objects.all() | |
for attr in attributes: | |
value = self.request.POST.get(attr.attribute) | |
item_attribute = ItemAttribute.objects.create(item=item, attribute=attr, value=value) | |
return super(ItemCreate, self).form_valid(form) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment