Django更新或插入重复的行

时间:2014-10-24 22:14:35

标签: django django-forms django-views

我创建了几个表单来编辑一些记录。当我保存表单时,我可以在数据库中看到应用程序更新记录并插入一两个记录。

我用来更新记录的所有表单都有这种奇怪的行为。我不知道错误是在表单定义中还是在视图定义中。

模型

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

我正在使用遗留数据库,我检查数据库的约束,过程,触发器,一切看起来都很好。 在表格旁边,不要使用任何程序功能等。

只有当我从应用程序更新或插入时,我才能看到这种行为。

更新

urls.py
urlpatterns = patterns('',
    url(r'^recepcion/$','prov.views.DetRecView',name='recepcion'),
    url(r'^newdetrec/$','prov.views.NewDetRecView',name='newdetrec'),
    url(r'^master/$','prov.views.NewMasterView',name='master'),
    url(r'^conci/$', 'prov.views.ConciView',name='conci'),
    url(r'^carga/$', 'prov.views.CargaView',name='carga'),
    url(r'^gencert/$', 'prov.views.GenCertView',name='gencert'),
    url(r'^entcert/$', 'prov.views.EntCertView',name='entcert'),
    url(r'^aceptacert/$', 'prov.views.AceptaCertView',name='aceptacert'),
    url(r'^envconci/$', 'prov.views.EnvConciView',name='envconci'),
)

我的创建视图(针对相同型号)

  @login_required(login_url='/login/')
    @permission_required('prov.views.configView',login_url='/login/')
    def NewDetRecView(request):
        form = NewDetRecForm(request.POST or None)
        if request.method == 'POST':
           idp = request.POST['id_proveedor']
           a = request.POST['anio']
           m = request.POST['mes']
           id = Proveedor.objects.get(id_proveedor=idp)
           obj,created = DetalleRecepcion.objects.get_or_create(id_proveedor=id,anio=a,mes=m)
           obj.save()
           return HttpResponseRedirect('/monitor/')

           if not created:
              obj.id_proveedor = id
              obj.anio = a
              obj.mes = m
              obj.save()
              return HttpResponseRedirect('/monitor/')
        return render_to_response('newdetrec.html',
                              {'form':form})

我的表单类创建新记录:

class NewDetRecForm(forms.ModelForm):
      def __init__(self,*args,**kwargs):
       super(NewDetRecForm,self).__init__(*args,**kwargs)
       self.helper = FormHelper(self)
       self.helper.layout.append(Submit('save','Grabar'))
       self.helper.layout = Layout(
        Fieldset('',
                 'id_proveedor',
                 'anio',
                 'mes',
                 Submit('save','Grabar'),
                )
       )
      def clean(self):
        cleaned_data = super(NewDetRecForm, self).clean()

        id_proveedor = self.cleaned_data['id_proveedor']
        #num_archivos = self.cleaned_data['num_archivos']
        anio = self.cleaned_data['anio']
        mes = self.cleaned_data['mes']

        qs = self.Meta.model.objects.filter(id_proveedor=id_proveedor, anio=anio, mes=mes)
        if self.instance:
            qs = qs.exclude(pk = self.instance.pk)
        if qs.count() > 0:
            raise forms.ValidationError(u'Registro ya existente')

        return cleaned_data
      class Meta:
        model = DetalleRecepcion

DetRecForm用于更新

DetRecView用于更新

NewDetRecForm用于创建

NewDetRecView用于创建

更新2

javascript函数传递参数

<script type="text/javascript">
  $(document).ready ( function () {
    $(document).on ("click", "#recepcion", function (event) {
        event.preventDefault();
        var tbl = document.getElementById("myTable");
        var idpro = $(this).parents('tr:first').find('td:first').text();
        var anio = $(this).closest('tr').children(":eq(1)").text();
        var mes = $(this).closest('tr').children(":eq(2)").text();
        var argu = "?i="+idpro+"&a="+anio+"&m="+mes;
        //window.location = "/recepcion/"+argu;
        var url = "/recepcion/"+argu;
        window.open(url,'_blank')
    });
});
</script>

我知道这不是将参数传递给模板的正确方法。 我开始学习AJAX来传递数据,但同时我使用了这个可怕的函数

1 个答案:

答案 0 :(得分:0)

url(r'^recepcion/add/$','prov.views.DetRecView',name='recepcion_add'),  # create object
url(r'^recepcion/edit/(?P<pk>\d+)/$','prov.views.DetRecView',name='recepcion_edit'),  # update object

让我们在视图功能中查看您的情况:if request.method=='POST'更好地使用if request.POST

所以当你有else时 - 意味着request.GET你得到DetalleRecepcion的实例(读取实例作为某个类的对象)并将其传递给你的ModelForm。它是更新对象方法(但您将此用于创建对象),并且提供的查询必须提供一个对象(唯一)。

如果您想将此视图用于创建更新,则必须更改您的网址(如上所述),您必须定义条件:{{1您已经更新对象if request.kwargs.get('pk'),您将转到创建对象。

主要区别在于,如果是更新,您必须为表单else提供实例,因此r = DetalleRecepcion.objects.get(pk=request.kwargs['pk'])(当DetRecForm(instance=r)时)和{{1 (request.GET时)。

如果您想在表单中提供一些初始数据(form = DetRecForm(request.POST, instance =r)时),请使用request.POST