Форма Django вставляет запись вместо записи обновления

У меня возникли проблемы с попыткой обновить некоторые записи в Django: когда я пытаюсь обновить какую-либо запись, приложение вставляет новую, я не знаю, почему у меня такое поведение.

Модель

class DetalleRecepcion(models.Model):
    id_proveedor = models.ForeignKey(Proveedor,db_column='id_proveedor',primary_key=True, verbose_name='Proveedor')
    anio = models.IntegerField( null=False)
    mes = models.IntegerField(verbose_name='Mes')
    fecha_recepcion = models.DateField(verbose_name='Fecha Recepcion')
    usuario = models.CharField(max_length=15, blank=True)
    num_archivos = models.IntegerField(primary_key=True, verbose_name='No de archivos')
    class Meta:
        managed = False
        db_table = 'mpc_detalle_recepcion'

Посмотреть:

@login_required(login_url='/login/')
def DetRecView(request):
    idp = request.GET.get('i')
    anio = request.GET.get('a')
    mes = request.GET.get('m')
    if request.method == 'POST':
       r = DetalleRecepcion.objects.get(id_proveedor=idp,anio=anio,mes=mes)
       form = DetRecForm(request.POST or None, instance =r)
       if form.is_valid():
          form.save()
          return HttpResponse('<script type="text/javascript">window.close()</script>')
    else:
       r = DetalleRecepcion.objects.get(id_proveedor=idp,anio=anio,mes=mes)
       r.usuario = request.user
       form = DetRecForm(instance=r)

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

Форма:

class DetRecForm(forms.ModelForm):
      fecha_recepcion = forms.DateField(widget=DateInput(),)
      def __init__(self,*args,**kwargs):
          super(DetRecForm,self).__init__(*args,**kwargs)
          self.helper = FormHelper(self)
          self.helper.layout = Layout(
           Field('id_proveedor',
                 'anio',
                 'mes',
                 'usuario',
                 readonly = True
                 ),
           Fieldset('',
                    'fecha_recepcion',
                    'num_archivos',
                    Submit('save','Grabar'),
                    HTML('<a class="btn btn-danger" id="cerrar">Cancelar</a>')
                    )
          )
      class Meta:
          model = DetalleRecepcion

Я использую то же определение вида и формы для других моделей для отображения форм редактирования, и с этим другие модели отлично работают, и записи обновляются. Я не понимаю, что случилось. Я переписываю форму, определение просмотра для этой модели и не знаю, в чем проблема. База данных является устаревшей базой данных, и таблицы не имеют каких-либо отношений или ограничений. Кстати, я использую хрустящую форму Django.

заранее спасибо


person Joseleg    schedule 21.10.2014    source источник


Ответы (2)


Если вы используете одну и ту же форму для создания и обновления представлений, вам необходимо предоставить чистый метод для вашего уникального поля и вызвать ValidationError, когда объект существует.

Но в вашем случае, я предполагаю, что вы используете составной первичный ключ для полей: id_proveedor, num_archivos, вы должны переопределить чистый метод всей формы:

class DetRecForm(forms.ModelForm):
    fecha_recepcion = forms.DateField(widget=DateInput())

    def __init__(self, *args, **kwargs):
        super(DetRecForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.layout = Layout(
            Field('id_proveedor',
                  'anio',
                  'mes',
                  'usuario',
                  readonly=True
            ),
            Fieldset('',
                     'fecha_recepcion',
                     'num_archivos',
                     Submit('save', 'Grabar'),
                     HTML('<a class="btn btn-danger" id="cerrar">Cancelar</a>')
            )
        )

    def clean(self):
        cleaned_data = super(DetRecForm, self).clean()

        id_proveedor = self.cleaned_data['id_proveedor']
        num_archivos = self.cleaned_data['num_archivos']

        qs = self.Meta.model.objects.filter(id_proveedor=id_proveedor, num_archivos=num_archivos)
        if self.instance:
            qs = qs.exclude(pk=self.instance.id)
        if qs.count() > 0:
            raise forms.ValidationError(u'Such object exists!')

        return cleaned_data

    class Meta:
        model = DetalleRecepcion
person madzohan    schedule 21.10.2014
comment
Спасибо за ответ, у меня есть целый месяц с python и django, и я делаю много ошибок новичка, и есть некоторые вещи, которые я не знаю, куда их поместить. Эта чистая функция, где я должен написать ее в определении формы или в представлении. и как я могу вызвать эту чистую функцию - person Joseleg; 21.10.2014
comment
В теле метода я назвал super(DetRecForm, self).clean(), поэтому вы должны поместить его в объявление DetRecForm, и вы не должны вызывать его вручную, который будет запускаться во время проверки формы автоматически, потому что вы переопределяете метод родительского класса 'clean' . - person madzohan; 21.10.2014
comment
Спасибо за ответ, не хочу вас беспокоить, но у меня другая проблема. эта модель имеет связь один ко многим с другой моделью. у одного провайдера может быть много записей detrec. но я получаю сообщение об ошибке id_proveedor уже зарегистрирован. Пару дней назад я разместил ссылку на этот поток . Я понимаю исключение, но я не знаю, как вставить данные. Мне нужно вставить id_provedor, anio и mes, но для первичного ключа я не могу это сделать. Любая идея, как я могу вставлять записи. - person Joseleg; 22.10.2014

Попробуйте получить объект, например, по pk

DetalleRecepcion.objects.get(pk=kwargs['pk'])
person Amir Asaad    schedule 21.10.2014