【问题标题】:Django form insert record instead of update recordDjango 表单插入记录而不是更新记录
【发布时间】:2014-12-16 23:34:13
【问题描述】:

我在尝试更新 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 脆皮表单

提前致谢

【问题讨论】:

    标签: python django django-forms django-crispy-forms


    【解决方案1】:

    如果您使用相同的表单来创建和更新视图,那么您需要在您的唯一字段上提供干净的方法并在对象存在时引发 ValidationError。

    但在您的情况下,我假设您在字段上使用复合主键:id_proveedor、num_archivos,您应该覆盖整个表单的 clean 方法:

    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
    

    【讨论】:

    • 感谢您的回复,我有一个月的时间使用 python 和 django,我犯了很多新手错误,有些东西我不知道该放在哪里。这个干净的函数我必须在表单定义或视图中编写它。以及如何调用这个干净的函数
    • 在方法体中我调用了 super(DetRecForm, self).clean(),所以你应该把它放在 DetRecForm 声明中,你不应该手动调用它,它会在表单验证时自动运行,因为你重写父类方法'clean'。
    • 感谢您的回答,我不想打扰您,但是我还有一个问题。该模型与另一个模型具有一对多的关系。一个提供者可以有许多 detrec 记录。但我得到错误 id_proveedor 已经注册。几天前,我发布了那个帖子link。我理解异常,但我不知道如何插入数据。我需要插入 id_proveedor、anio 和 mes,但是对于主键我做不到。知道如何插入记录。
    【解决方案2】:

    例如尝试通过pk获取对象

    DetalleRecepcion.objects.get(pk=kwargs['pk'])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-18
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多