Да, сошлось, работает.
Единственное что я добавил от себя, чтобы вручную не создавать каждую форму, то в ваш код я добавил ещё одно поле в PartialForm - variant, где перечислил все поля для которых надо создавать формы. Если быть более точным, то у меня в этой модели надо было часть полей сделать отдельными формами, а некоторые поля группировались по определённому признаку и каждая группа в своей форме. Поэтому у меня получился такой вот код:
class FullExecutorForm(ModelForm):
class Meta:
model = Executor
fields = ('city', 'phone', 'm_phone', 'work_cats', 'social_url1', 'social_url2', 'f_langs_list', 'dl', 'dl_cats', 'p_car', 'about', 'hour_price', 'hour_cur')
class PartialExecutorForm(ModelForm):
variants = (
('city',),
('phone',),
('m_phone',),
('work_cats',),
('social_url1',),
('social_url2',),
('f_langs_list',),
('dl', 'dl_cats', 'p_car',),
('about',),
('hour_price', 'hour_cur',),
)
class Meta:
model = Executor
fields = ()
def __init__(self, *args, **kwargs):
super(PartialExecutorForm, self).__init__(*args, **kwargs)
if self.data:
base_form = FullExecutorForm()
self.fields.update({key:base_form.fields[key] for key, value in self.data.items() if key in base_form.fields})
И теперь можно пройтись в цикле по variant и создать все формы. В качестве названия формы я выбрал <название первого из полей>_form чтобы не заморачиваться.
Но возникла новая трудность, форма получалась пустой.
Не знаю, может вы сможете подсказать более хорошее решение, но я решил эту проблему так:
for variant in PartialExecutorForm.variants:
data = {}
for f in executor._meta.concrete_fields:
if f.name in variant:
data[f.name] = f.value_from_object(executor)
for f in executor._meta.many_to_many:
if f.name in variant:
qs = f.value_from_object(executor)
if qs._result_cache is not None:
data[f.name] = [item.pk for item in qs]
else:
data[f.name] = list(qs.values_list('pk', flat=True))
form = PartialExecutorForm(data)
form_name = '%s_form' % variant[0]
context[form_name] = form
Надёргал куски из кода django :)
Осталась только одна проблема - сохранение присланной формы в базу. Даже не знаю в чём проблема, но не сохраняет.
Когда получаю форму заполненную от клиента, создаю её так же:
if request.POST:
try:
form = PartialExecutorForm(request.POST, instance=request.user.executor)
if form.is_valid():
a = form.save()
При этом просматриваю форму после того как сделан is_valid(), через print form в консоль, данные получены те которые я ввёл. Но вот когда я делаю print a.<измененённое поле> то там всё без изменений.
Например, в коде добавляю вывод в консоль:
if request.POST:
try:
form = PartialExecutorForm(request.POST, instance=request.user.executor)
if form.is_valid():
a = form.save()
print form
print a.dl_cats
Исходно в базе было в поле dl_cats значение 'A, B'. Я в форме ввожу 'A, B, C' и отправляю на сервер.
Получаю такой вывод в консоли:
<tr><th><label for="id_dl_cats">Список открытых категорий:</label></th><td><input id="id_dl_cats" maxlength="200" name="dl_cats" type="text" value="A, B, C" /></td></tr>
A, B
Т.е. в форме то верное значение, а объект не поменялся.
В чём может быть дело и как это побороть?