Редактирование экземпляра модели с помощью ModelForm создает новый экземпляр вместо обновления - PullRequest
4 голосов
/ 28 мая 2011

Я пытаюсь создать представление, позволяющее пользователю редактировать экземпляр модели (в данном случае событие). К сожалению, отправка этой формы создает новый экземпляр (с новым идентификатором) и даже не удаляет старый экземпляр. У меня сложилось впечатление, что метод save должен обновить экземпляр в этом случае ...

ПРИМЕЧАНИЕ. EventForm - это ModelForm

Я пытался использовать аргумент force_update для https://docs.djangoproject.com/en/dev/ref/models/instances/#forcing-an-insert-or-update,, но без игры в кости. Я также попытался просто удалить исходное событие в блоке form.is_valid() (вызвав event.delete()), но .... без кубика.

У меня такое чувство, что проблема commit=False? Я не уверен!

Спасибо.

(Пожалуйста, игнорируйте проблемы с пробелами в фрагменте кода)

def edit_event(request, event_id):
 event = Event.objects.get(pk=event_id)  

 if request.method == 'POST':
     post_data = request.POST.copy()

     # here is some validation that can't be done in the ModelForm...

     #form = EventForm(post_data, request.FILES, instance=event)
     form = EventForm(post_data, request.FILES)

     if form.is_valid():

         edited_event = form.save(commit=False)

         edited_event.save(force_update=True) # doesn't work with or without force_update arg

         #form.save_m2m() # needed for ManyToMany relationship

         return HttpResponseRedirect('/events/view/%s' % edited_event.id)
  else:
      form = EventForm(instance=event)

return render_to_response('create_event.html', {'form': form,}, context_instance=RequestContext(request) )

UPDATE

Я избавился от отношения M2M на моей модели, поэтому я могу избавиться от линии form.save_m2m(). Это все еще не работает.

Я также пытался не передавать экземпляр при отправке формы, предполагая, что правильные поля будут предварительно заполнены при отправке пользователем (что имеет место сейчас). Это все еще не работает.

Не хватает важной детали при обновлении модели?

Ответы [ 4 ]

5 голосов
/ 14 августа 2012

Я думаю, вы должны инициализировать форму следующим образом (как вы уже прокомментировали).

form = EventForm(post_data, request.FILES, instance=event)

Тогда объект события связывается с формой, и form.save() может выполнить обновление вместо вставки.

2 голосов
/ 15 июня 2011

Насколько я понимаю, проблема с вашим кодом заключается в том, что вы всегда создаете новый экземпляр перед сохранением.Поскольку вы уже получили экземпляр события в "event = Event.objects.get (pk = event_id)", вы можете просто изменить этот экземпляр и сохранить его, и я совершенно уверен, что это заставит django создатьupdate.

Советую проверить эту ссылку: https://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs#how-django-knows-to-update-vs-insert

В ней довольно простое объяснение алгоритма, используемого Django для различения между вставками и обновлениями.Если у вашего объекта не установлен первичный ключ (возможно, это поле «id», которое django создает автоматически при синхронизации), он будет рассматриваться как новый объект.Если у него установлено это поле, Django попытается найти эту конкретную запись в базе данных, если она существует, она будет обновлена.

Надеюсь, ответ был достаточно ясен.

0 голосов
/ 14 января 2017

Профиль показывает и обновляет рабочий код:

@login_required(login_url=LOGIN_URL)
@csrf_exempt
def profile(request):
    """
    :param request:
    :param:
    :return:
    """
    val = get_object_or_404(Profil, user=request.user)

if request.method == 'POST':
    form = ProfilForm(request.POST, request.FILES, instance=val)
    if form.is_valid():
        form.save()
        msg_ok = u'Profil updated'
    else:
        msg_err = u"Invalid form."
else:
    form = ProfilForm(instance=val)

return render(request, "back/profile.html", locals())
0 голосов
/ 28 мая 2011

Ваш пример слишком сложен.Попробуйте начать с нуля с простой моделью / видом / формой.Создайте новую модель с одним простым полем, затем создайте форму модели и представление и убедитесь, что они работают.Затем начните изменять вид, чтобы приблизить его к фактическому состоянию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...