数据已存在于模型中时更新记录

时间:2016-01-25 17:44:05

标签: python django django-models django-views

我有一个用户可以上传多个文件的视图。

@login_required(login_url='/login/')
def FileUploadView(request):
    if request.method == 'POST':
       form = CallgateUploadForm(request.POST,request.FILES)
       fecha = datetime.date.today()
       if form.is_valid():
          for each in form.cleaned_data['archivo']:
              Callgate_Syni.objects.create(fecha=fecha,archivo=each)
          os.system('/home/pyc/DjangoProjects/tap_app/media/docs/callgate/envia.sh')
          return HttpResponseRedirect('/lista/')
    else:
       form = CallgateUploadForm()
    return render_to_response('callgateupload.html',
                              {'form':form},
                              context_instance=RequestContext(request))

形式:

class CallgateUploadForm(forms.ModelForm):

      archivo = MultiFileField(min_num=1, max_num=20, max_file_size=1024*1024*5)
      def __init__(self,*args,**kwargs):
         super(CallgateUploadForm,self).__init__(*args,**kwargs)
         self.helper = FormHelper(self)
      class Meta:
            model = Callgate_Syni

在同一天,用户可以多次上传同一个文件,这会为同一个文件创建一个重复的记录(" archivo")。如何避免插入已上传文件的信息。 或者,如果文件已存在,则更新模型中的记录,如果文件不存在,则插入记录。

提前致谢。

3 个答案:

答案 0 :(得分:1)

您需要的是Django QuerySet update_or_create()方法。

用法很简单:

updated_values = {'archivo': archivo}
obj, created = Callgate_Syni.objects.update_or_create(fecha=fecha, defaults=updated_values)
if created: 
    print('The object was created')
else:
    print('The object was updated')

关键字args是指定记录是否存在的过滤器,defaults参数是带有要更新字段的filedname: fieldvalue字典。

返回元组具有创建或更新的对象,以及指示对象是否已创建的标志。

答案 1 :(得分:1)

从说明和for each in form.cleaned_data['archivo']:我了解您的需求:

  • 如果所有文件都是新文件,只需保存并创建;
  • 如果某些文件已存在,请更新它们并插入新文件。

因此,您可能希望为文件名指定日期标志,以便您可以检查文件是否已存在特定日期和文件名。例如,sample_file_20160125.csv将指示名为' sample_file.csv'的文件。已经被用户上传2016年1月25日。然后你可以在数据库中匹配这样的文件,如果找到,则更新文件对象;如果没有找到,请创建一条新记录。

如果您只想保存文件而不是在文件已存在时触摸数据库,请使用exists()检查数据库中的记录。

...
if not Callgate_Syni.objects.filter(fecha=fecha,archivo=each).exists():
    Callgate_Syni.objects.create(fecha=fecha,archivo=each)
os.system('/home/pyc/DjangoProjects/tap_app/media/docs/callgate/envia.sh')
...    

答案 2 :(得分:0)

您不能依赖文件名,而是依赖于其内容,因此一个想法是使用哈希函数。因此,一个解决方案是:

  1. 将哈希字段添加到文件模型中。

  2. 上传文件时,计算其内容的哈希值,不带名称,这样就不会影响生成的哈希值。

  3. 将文件保存到磁盘,将其哈希保存到DB。

  4. 当用户上传另一个文件时,计算其哈希并查看是否在DB中有相同哈希的记录。

    一个。如果没有,请转到第3步。

    湾如果是什么都不做。

  5. 计算哈希的缺点需要资源,但它比文件名更可靠。