How to save multiple values from dropdown with foreign key
I want to save multiple store ids in Test table in store_id column. What is the best way to design model to save multiple store ids in Test table models.py
class Store(models.Model):
store_name = models.CharField(max_length=100, verbose_name="store")
def __unicode__(self):
return '%s' %(self.name)
def __str__(self):
return self.name
class Test(models.Model):
store_id = models.ForeignKey(Store, on_delete=models.CASCADE, db_column='store_id')
def __unicode__(self):
return '%s' %(self.id)
Forms.py
class TestForm(ModelForm):
def __init__(self, *args, **kwargs):
self.fields['store_id'] = ModelChoiceField(queryset=Store.objects.all(), widget=SelectMultiple(attrs={'class':'form-control'})
class Meta:
model = Test
fields = ('store_id',)
I want to save multiple store ids in Test table in store_id column.
You can't. This is a field that essentially mimics the column of the primary key of a Store, so it can contain only one such value.
A ManyToManyField [Django-doc], this will create a junction table [wiki] in between that wil link to a Store and a Test, so:
class Store(models.Model):
name = models.CharField(max_length=100, verbose_name='store')
def __str__(self):
return self.name
class Test(models.Model):
stores = models.ManyToManyField(Store)
def __str__(self):
return f'{self.id}'
In the form, this will work with a ModelMultipleChoiceField [Django-doc]:
class TestForm(ModelForm):
def __init__(self, *args, **kwargs):
self.fields['stores'].widget.attrs.update(class='form-control')
class Meta:
model = Test
fields = ('stores',)
Note: Normally one does not add a suffix
…_idto aForeignKeyfield, since Django will automatically add a "twin" field with an…_idsuffix. Therefore it should bestore, instead of.store_id
To save multiple store IDs in the Test table from a dropdown you need to switch your store_id field in the Test model to use a ManyToManyField instead of a ForeignKey.
Update your models.py like this:
from django.db import models
class Store(models.Model):
store_name = models.CharField(max_length=100, verbose_name="store")
def __str__(self):
return self.store_name
class Test(models.Model):
store_id = models.ManyToManyField(Store)
def __str__(self):
return f'Test {self.id}'
Then update your forms.py with this:
from django.forms import ModelForm, ModelMultipleChoiceField, SelectMultiple
from .models import Test, Store
class TestForm(ModelForm):
def __init__(self, *args, **kwargs):
super(TestForm, self).__init__(*args, **kwargs)
self.fields['store_id'] = ModelMultipleChoiceField(
queryset=Store.objects.all(),
widget=SelectMultiple(attrs={'class':'form-control'})
)
class Meta:
model = Test
fields = ('store_id',)
You used both __str__ and __unicode__ methods in your models which is not necessary, in Python 3 and Django versions supporting Python 3, you should only define the __str__ method for your models. The __unicode__ method was used in Python 2 to ensure that the representation of non-ASCII characters is handled correctly. Since Python 3 uses Unicode by default for strings, __unicode__ is no longer necessary.