Как сохранить несколько значений из выпадающего списка с внешним ключом
Я хочу сохранить несколько идентификаторов магазинов в таблице Test в столбце store_id. Как лучше всего спроектировать модель для сохранения идентификаторов нескольких магазинов в таблице Test 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',)
Я хочу сохранить несколько идентификаторов магазинов в таблице Test в столбце store_id.
Нельзя. Это поле, которое по сути имитирует столбец первичного ключа Store
, поэтому оно может содержать только одно такое значение.
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}'
В форме это будет работать с 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',)
Примечание: Обычно не добавляют суффикс
…_id
к полюForeignKey
, так как Django автоматически добавит поле-"близнец" с суффиксом…_id
. Поэтому он должен бытьstore
, вместо.store_id
Чтобы сохранить несколько идентификаторов магазинов в таблице Test
из выпадающего списка, необходимо переключить поле store_id
в модели Test
на использование ManyToManyField
вместо ForeignKey
.
Обновите свой models.py
следующим образом:
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}'
Затем обновите свой forms.py
следующим образом:
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',)
Вы использовали оба метода __str__
и __unicode__
в своих моделях, что не является необходимым, в Python 3 и версиях Django, поддерживающих Python 3, вы должны определить только метод __str__
для своих моделей. Метод __unicode__
использовался в Python 2 для обеспечения корректного представления символов non-ASCII
. Поскольку Python 3 по умолчанию использует Unicode для строк, __unicode__
больше не нужен.