Чтобы добавить к ответу Кайла,
Создание пользовательской формы - единственный способ настроить поле «многие ко многим» таким образом.Но, как я обнаружил, этот метод работает, только если вы изменяете экземпляр этой модели.(по крайней мере, в Django 1.5)
Это потому, что: self.instance
вернет объект Model.(Я знаю сумасшедшую концепцию) Но если вы создаете экземпляр этой модели, поскольку эта модель еще не создана, self.instance
вернет исключение DoesNotExist
.
Чтобы обойти эту проблему, создайте две формы:
class MyModelChangeForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self, *args, **kwargs):
super(MyModelChangeForm, self).__init__(*args, **kwargs)
my_model = self.instance
self.fields['fields'].queryset = OtherRelatedModel.objects.filter(other_id=my_model.other)
class MyModelCreationForm(forms.ModelForm):
class Meta:
model = MyModel
def save(self, commit=True):
my_model = super(MyModelCreationForm, self).save(commit=False)
*** Do other things with the my_model if you want ***
my_model.save()
return my_model
Затем внутри admin.py мы создадим отдельный набор полей для нашей формы создания:
class MyModelAdmin(admin.ModelAdmin):
filter_horizontal = ('other')
list_display = ('field1', 'field2' 'field3')
fieldsets = (
("Model info:", {'fields': ("field1", "field2", "field3")}),
("More Model info:", {'fields': ("other",)}),
)
add_fieldsets = (
("Initial info:", {'fields': ("field1", "field2", "field3")}),
)
form = MyModelChangeForm
add_form = MyModelCreationForm
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
return super(MyModelAdmin, self).get_fieldsets(request, obj)
def get_form(self, request, obj=None, **kwargs):
"""
Use special form during MyModel creation
"""
defaults = {}
if obj is None:
defaults.update({
'form': self.add_form,
'fields': admin.util.flatten_fieldsets(self.add_fieldsets),
})
defaults.update(kwargs)
return super(MyModelAdmin, self).get_form(request, obj, **defaults)
Обратите внимание, что нам пришлосьпереопределите get_form и get_fieldsets, что если obj имеет значение None (или, другими словами, если запрос должен добавить экземпляр модели), он использует MyModelCreationForm.Это тот же метод, который используют разработчики django в django.contrib.auth.admin для получения своей пользовательской формы UserCreation и наборов полей.(Посмотрите в сторону исходный код для этого примера)
Наконец, модели будут выглядеть примерно так в model.py:
class MyModel(models.Model):
*** field definitions ***
other = models.ManytoManyField(OtherRelatedModel, null=True, blank=True)
class OtherRelatedModel(models.Model):
other_id = model.AutoField(primary_key=True)
*** more field definitions ***
Единственная причина, по которой я включил модели, это то, что вымог видеть определение поля многие ко многим в классе MyModel.Для не нужно, чтобы имел пустое и пустое значение True.Просто помните, что если вы этого не сделаете, вам придется либо присвоить им значение по умолчанию в определении, либо установить их в функции save () в MyModelCreationForm.
Надеюсь, это поможет!(Если это совершенно неправильно, пожалуйста, поправьте меня! Мне тоже нужно учиться.)
-Спасибо