Джанго: Проверьте тип отношения формы - PullRequest
1 голос
/ 20 января 2010

У меня есть ситуация, когда мне нужно проверить, имеет ли форма отношение m2m, прежде чем сохранять ее в views.py, поскольку я использую один и тот же views.py для разных моделей.

Пример:

#models.py
class BaseClass(models.Model):
   # Some generic stuff.

class SomeClass(BaseClass):
   # This class doesnt have any many2many relations

class SomeOtherClass(BaseClass):
   # This class has many2many relations

#views.py
def do_some_stuff(request):
   # Instantiate a form
   # Save it in a normal way
   form.save()
   # Now, in here while saving I need to check if the form has any 
   # m2m relations so I can use the save_m2m() function after form.save()

Мне просто нужна дополнительная проверка, чтобы быть на более безопасной стороне. Есть ли способ обойти это? Заранее спасибо

Ответы [ 4 ]

0 голосов
/ 20 января 2010

Фактически, save_m2m() всегда вводится в ModelForm экземпляр после save(commit=False). Даже если в модели нет полей ManyToMany.

Вот источник save_m2m функции:

def save_m2m():
    opts = instance._meta
    cleaned_data = form.cleaned_data
    for f in opts.many_to_many:
        if fields and f.name not in fields:
            continue
        if f.name in cleaned_data:
            f.save_form_data(instance, cleaned_data[f.name])

Если нет полей ManyToMany (instance._meta.many_to_many = []), ничего не будет сделано.

Так что во всех случаях вы можете спокойно звонить save_m2m.

0 голосов
/ 20 января 2010

Я только что выяснил возможное решение для этого.

Вы можете использовать что-то вроде этого:

if len(form_instance._meta.many_to_many) > 0:
   for i in form_instance._meta.many_to_many:
      if type(i) = ManyToManyField:
         form_instance.save_m2m()
         break
0 голосов
/ 20 января 2010

Антоний прав, и это еще проще, я цитирую документацию :

Еще один побочный эффект использования commit=False наблюдается, когда ваша модель имеет отношение многие ко многим с другой моделью. Если ваша модель имеет отношение «многие ко многим» и вы указываете commit=False при сохранении формы, Django не может сразу сохранить данные формы для отношения «многие ко многим». Это связано с тем, что невозможно сохранить данные «многие ко многим» для экземпляра до тех пор, пока этот экземпляр не появится в базе данных.

Чтобы обойти эту проблему, каждый раз, когда вы сохраняете форму, используя commit=False, Django добавляет метод save_m2m() в ваш подкласс ModelForm.

В соответствии с этим, если вы не сохраните форму с помощью commit=False, метод save_m2m() даже не существует , независимо от того, существуют отношения многие ко многим.

Верный девизу Python «просить прощения легче, чем разрешение», вы также можете сделать:

try:
    form.save_m2m()
except:
    pass

если вы действительно хотите.

0 голосов
/ 20 января 2010
if hasattr(form, 'save_m2m'):
    form.save_m2m()

Следует помнить, что save_m2m необходим (и существует только), когда вы вызываете form.save с аргументом commit=False. Если вы сохраните его с commit=True, который является значением по умолчанию, в save_m2m.

нет необходимости.
...