Django 错误 <model> 对象没有属性“更新”

Posted

技术标签:

【中文标题】Django 错误 <model> 对象没有属性“更新”【英文标题】:Django error <model> object has no attribute 'update' 【发布时间】:2013-02-24 14:38:56 【问题描述】:

更新

我正在对服务器进行一些维护并重新启动......一旦它回来,代码就可以正常工作......这实际上让我同样担心......

我认为这是 mod_wsgi 的一个错误。

还是谢谢!

我真的是 django 的新手(昨天开始)。我设法使用 xlrd 制作了一个 excel 解析器,数据一切正常(它加载非常快),我需要更新数据库中的文件信息,这样我就可以知道负载是如何进行的,这就是我拥有的地方问题,save() 方法不起作用,我已经使用了 update 以及 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)

我在模型文件中找不到对此错误的任何引用或其他要添加的内容,我很确定这很容易修复,但我就是找不到。

我得到的错误(对于所有不同的代码)是

异常类型:AttributeError at /procesa/4

异常值:'archivo' 对象没有属性'update'

文件的记录被解析并插入没有问题。

我在 Apache 2.2 中使用 Django 1.5 和 python 2.7,并在 Amazon 的 EC2 中安装了 mod_wsgi 和 mysql 后端

更新 我正在对服务器进行一些维护并重新启动......一旦它回来,代码就可以正常工作......这实际上让我同样担心......

我认为这是 mod_wsgi 的一个错误。

还是谢谢!

【问题讨论】:

您覆盖了您未在模型中定义的更新。重写您使用更新方法的代码或在模型中定义更新方法以便您可以使用它 【参考方案1】:

这个错误的原因是.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)

请注意,如果多个对象存在,这将更新它们。如果您想确保不会发生这种情况,您应该在过滤器中包含主键,或者使用较早的方法之一来确保您只修改单个对象。

【讨论】:

【参考方案2】:

遇到此行为并使用“过滤器”然后更新按预期工作。例如:

 Students.objects.select_for_update().filter(id=3).update(score = 10)

仅供参考:除非您正在处理事务,否则使用 save() 单独修改每个字段可能会在多线程环境中造成数据不一致。当 threadA 在模型上调用 save() 时,另一个 threadB 可能已经更改了模型字段并保存了。在这种情况下,threadA 必须读取更新的模型并进行更改。

这是在 Django 1.6.2 上

【讨论】:

【参考方案3】:

我也遇到过类似的情况,但是在使用以下结构时它起作用了:

this_spot = Spot.objects.filter(pk=obj.spot.pk)
this_spot.update(friendly_rate=rating_to_be_persisted)

但在我想直接访问单个实例的情况下不起作用,例如从外键端类。返回'Spot' object has no attribute 'update'

原因只是update() 的工作方式在django documentation 中描述:

解决方法是 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')

【讨论】:

【参考方案4】:

我没有浏览你所有的代码,但是这一行:

 infoarchivo2 = archivo.objects.filter(archivo_id = procesar)

不从数据库返回实例或对象,它返回一个查询集,即使查询集只有一个元素。您将不得不迭代 Queryset oy 或者更改 get 的方法过滤器。

只要方法更新,我认为没有实现。

【讨论】:

以上是关于Django 错误 <model> 对象没有属性“更新”的主要内容,如果未能解决你的问题,请参考以下文章

Django之models之查询表

我正在尝试在 django 中添加多对多字段但出现错误

django models视图基本操作

无法分配“<class 'django.contrib.auth.models.User'>”:“Model.user”必须是“User”实例

原Django数据Model层总结

Django model对象接口