model.AutoField - form.save () создает новые записи (INSERT) вместо обновления существующих - PullRequest
2 голосов
/ 19 октября 2011

Ситуация : Наличие базы данных mysql с некоторыми данными. Для этого примера я использую только два поля; id и subject . id определяется как Integer с опцией * auto_increment *, тогда как subject - это просто обычный varchar. Код:

Модель

class AList(models.Model):
    id=models.AutoField(primary_key=True, db_column='ID')
    subject=models.CharField(max_length=200, db_column='SUBJECT')
    class Meta:
        db_table = u'alist'

Форма

class AForm(ModelForm):
    class Meta:
        model=AList

View :

def alistForm(request,a_id=None):
    if a_id:
        a=AList.objects.get(id=a_id)
        form=AForm(instance=a)
    else:
        form=AForm(request.POST or None)
    return render_to_response('aform.html',{'form':form},context_instance=RequestContext(request)

def alistPost(request):
    form=AForm(request.POST or None)
    if form.is_valid():
        form.save()

Описание проблемы: Когда форма отправляет новые данные в функцию alistPost, form.save () вставляет новую запись, как и должно быть. Но когда я редактирую уже существующую запись, она тоже вставляется как новая запись ... и не обновляется, как должно.

Попытка изменить идентификатор с AutoField на IntegerField меняет поведение: при изменении записи form.save () изменяет существующую, при попытке вставить новую запись происходит сбой, поскольку у него нет идентификатора.

Вопрос: Нужно ли мне вручную получать новое значение ID из базы данных и заставлять Django использовать его для этой новой записи, или есть способ заставить Django автоматически определить, следует ли ему использовать INSERT или UPDATE?

Ответы [ 3 ]

4 голосов
/ 19 октября 2011

Драгун на правильном пути, но ваш комментарий делает правильное замечание. Лучшая модель выглядит так:

if a_id:
    a = AList.objects.get(id=a_id)
else:
    a = AList()
if request.POST:
    form = AForm(request.POST, instance=a)
    ...
else:
    form = AForm(instance=a)
1 голос
/ 20 декабря 2011

Это то, что я сделал:

def someView(request,id=None):
   instance = form = None

   ...
      ...
   elif request.method == 'POST':

        if id != None:
            instance = SomeClass.objects.get(id=id)
            form = AForm(request.POST,instance=instance)
        else:
            form = AForm(request.POST) 

        if form.is_valid():

           instance = form.save()
           if not id:
               return redirect('edit',id=instance.id)
        else
            ...
        ...

urls:

url(r'^addedit/$', 'som.views.someView', name='edit'),
url(r'^addedit/(?P<id>.*)/$', 'som.views.someView', name='edit'),

, поэтому после создания объекта в / addit / пользователь перенаправляется в / addit / 1234 /

0 голосов
/ 19 октября 2011

Проблема в том, что вы выполняете POST в отдельной функции, в которой вы не передаете instance аргумент в форму.

Попробуйте объединить функции в одну из них:

def alistForm(request, pk)
    alist = get_object_or_404(AList, pk=pk)
    form = AFrom(request.POST or None, instance=alist)
    if request.method == 'POST':
        if form.is_valid():
            form.save()
    ...
...