Объект ошибки Django <model> не имеет атрибута 'update'

UPDATE

Я делал некоторое обслуживание на сервере и перезагружался... как только он вернулся, код работал просто отлично... что на самом деле заставляет меня беспокоиться точно так же...

Я думаю, что это ошибка в mod_wsgi.

Спасибо в любом случае!

Я действительно новичок в django (начал вчера). Мне удалось сделать синтаксический анализатор excel с помощью xlrd, все отлично работает с данными (он действительно загружается очень быстро), мне нужно обновить информацию о файле в базе данных, чтобы я мог знать, как происходит загрузка, вот где у меня есть проблема, метод 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)

Я не могу найти ссылку на эту ошибку или что-то еще, чтобы добавить в файл моделей, я уверен, что это действительно легко исправить, но я просто не могу ее найти.

Ошибка, которую я получаю (для всех разных кодов),

Тип исключения: AttributeError at/procesa/4

Исключительное значение: объект 'archivo' не имеет атрибута 'update'

Записи файла анализируются и вставляются без проблем.

Я использую Django 1.5 с python 2.7 в Apache 2.2 с mod_wsgi и mysql файлом, установленным в EC2 на Amazon

UPDATE Я делал некоторое обслуживание на сервере и перезагружался... как только он вернулся, код работал нормально... что на самом деле заставляет меня беспокоиться точно так же...

Я думаю, что это ошибка в mod_wsgi.

Спасибо в любом случае!

Ответ 1

Причина этой ошибки заключается в том, что .get() возвращает отдельный объект, а .update() работает только с .filter(), например, что будет возвращено с помощью .filter() вместо .get().

Если вы используете .get(), то .update() не будет работать. Вам нужно будет сохранить информацию на объекте вручную:

archivo = archivo.objects.get(archivo_id = procesar)
archivo.archivo_registros = sh.nrows
archivo.save()

Вы также можете использовать update_fields, если хотите сохранить только этот конкретный фрагмент данных:

archivo.save(update_fields=['archivo_registros'])

Это предотвращает запуск любых сигналов, которые вы, возможно, не хотите вызывать.

Ответ 2

Обнаружено это поведение и используется "фильтр", а затем обновление работает, как ожидалось. Например:

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

Просто FYI: если вы не обрабатываете транзакции, изменение каждого поля отдельно с помощью 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:

Поворот - это подход, как показано на сайте 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, даже если Queryset имеет только один элемент. Вам придется перебирать Queryset, возможно, изменить фильтр метода для get.

Пока обновление метода, я не думаю, что оно реализовано.