更新
我正在对服务器进行一些维护并重新启动......一旦它回来,代码工作得很好......这实际上让我担心一样......
我认为这是mod_wsgi的一个错误。
非常感谢!
我是django的新手(昨天开始)。我设法使用xlrd制作一个excel解析器,一切都能很好地处理数据(它加载真的非常快),我需要更新数据库中的文件信息,这样我才能知道负载是怎么回事,这就是我所拥有的问题,save()方法不起作用,我已经使用了更新以及get和filter,但总是出现同样的问题。
我希望你能指出我的错误在哪里
models.py
class archivo(models.Model):
archivo_id = models.AutoField(primary_key=True)
fk_cliente = models.IntegerField()
fk_usuario = models.IntegerField()
archivo_nombre = models.CharField(max_length = 30)
archivo_original = models.CharField(max_length = 255)
archivo_extension = models.CharField(max_length = 5)
archivo_tamano = models.FloatField()
archivo_registros = models.IntegerField()
archivo_registros_buenos = models.IntegerField()
archivo_registros_malos = models.IntegerField()
archivo_registros_cargados = models.IntegerField()
archivo_fecha_carga = models.DateTimeField()
archivo_fecha_envio = models.DateTimeField()
def __unicode__(self):
return self.archivo_id
views.py
from procesa.models import *
from django.conf import settings
from django.shortcuts import render_to_response
import xlrd
from time import strftime
from symbol import except_clause
def procesa(request, procesar = 0):
datos = None
infoarchivo = None
if(procesar > 0):
try:
infoarchivo = archivo.objects.get(archivo_id=int(procesar))
except:
return render_to_response('error.html')
if (infoarchivo is not None):
excel_path = settings.FILES_URL+infoarchivo.archivo_original
wb = xlrd.open_workbook(str(excel_path))
sh = wb.sheet_by_index(0)
##START UPDATE##
infoarchivo2 = archivo.objects.filter(archivo_id = procesar)
infoarchivo2.archivo_registros = sh.nrows
infoarchivo2.save()
##END UPDATE##
for rownum in range(sh.nrows):
destino = str(sh.cell(rownum,0).value)
destino = destino.replace(".0","")
if (int(destino) > 0):
mensaje = str(sh.cell(rownum,1).value)
ahora = strftime("%Y-%m-%d %H:%M:%S")
reg = registro.objects.filter(registro_destino__exact=destino,fk_archivo__exact=procesar)
#reg = registro.objects.raw(str(el_query))
if (reg.exists()):
exists = True
else:
r = registro(fk_cliente=1,fk_usuario=1,fk_archivo=int(procesar),registro_destino=destino,registro_mensaje=mensaje,registro_estado='Cargado',registro_fecha_carga=ahora)
r.save()
datos = {'ID':procesar,'PATH': settings.FILES_URL, 'INFO':infoarchivo, 'el_excel':infoarchivo.archivo_original, 'registros':sh.nrows }
return render_to_response('carga.html', {'datos': datos})
在## START UPDATE ##块中,我已经尝试了
infoarchivo.archivo_registros = sh.nrows
infoarchivo.save()
和
archivo.objects.filter(archivo_id = procesar).update(archivo_registros=sh.nrows)
和
archivo.objects.get(archivo_id = procesar).update(archivo_registros=sh.nrows)
我在模型文件中找不到任何对此错误或其他内容的引用,我很确定它很容易修复,但我找不到它。
我得到的错误(对于所有不同的代码)是
异常类型:/ procesa / 4
的AttributeError异常值:'archivo'对象没有属性'update'
解析并插入文件的记录没有问题。
我在Apache 2.2中使用带有python 2.7的Django 1.5,在亚马逊上的EC2中安装了mod_wsgi和mysql后端
更新 我正在服务器上进行一些维护并重新启动......一旦它恢复,代码工作得很好......这实际上让我担心一样......
我认为这是mod_wsgi的一个错误。
非常感谢!
答案 0 :(得分:8)
出现此错误的原因是.get()
返回单个对象,.update()
仅适用于查询集,例如.filter()
而不是.get()
返回的内容。
如果您使用.get()
,那么.update()
将无效。您需要手动将信息保存到对象:
archivo = archivo.objects.get(archivo_id=procesar)
archivo.archivo_registros = sh.nrows
archivo.save()
如果您只想保存此特定数据,也可以使用update_fields:
archivo = archivo.objects.get(archivo_id=procesar)
archivo.archivo_registros = sh.nrows
archivo.save(update_fields=['archivo_registros'])
这可以防止触发您可能不想调用的任何信号。
您的另一个选择就是使用.filter()
。
archivo = archivo.objects.filter(archivo_id=procesar).update(archivo_registros=sh.nrows)
请注意,这将更新多个对象(如果存在)。如果您想确保不会发生这种情况,您应该使用其中一种早期方法来确保您只修改单个对象。
答案 1 :(得分:4)
遇到此行为并使用“过滤器”,然后更新按预期工作。例如:
Students.objects.select_for_update().filter(id=3).update(score = 10)
仅供参考:除非您正在处理事务,否则使用save()
单独修改每个字段可能会在多线程环境中造成数据不一致。当threadA在模型上调用save()
时,另一个threadB可以更改模型字段并保存。在这种情况下,threadA必须读取更新的模型并进行更改。
这是关于Django 1.6.2
答案 2 :(得分:2)
我有类似的情况,但在使用类似的结构时它起作用了:
this_spot = Spot.objects.filter(pk=obj.spot.pk)
this_spot.update(friendly_rate=rating_to_be_persisted)
但不工作的情况下,我希望直接访问单个实例,例如来自外键副端。返回'Spot' object has no attribute 'update'
。
原因很简单就是django documentation中描述的update()
工作方式:
方法就像在django网站上显示的那样:
>>> b = Blog.objects.get(pk=1)
# Update all the headlines belonging to this Blog.
>>> Entry.objects.select_related().filter(blog=b).update(headline='Everything is the same')
答案 3 :(得分:0)
我没有完成你的所有代码,但这一行:
infoarchivo2 = archivo.objects.filter(archivo_id = procesar)
不从数据库返回实例或对象,它返回Queryset,即使Queryset只有一个元素。您必须迭代Queryset,或者更改get的方法过滤器。
只要方法更新,我认为它没有实现。