开发者

django brookie - 'NoneType' object has no attribute 'status'

开发者 https://www.devze.com 2023-02-06 13:39 出处:网络
Bumped into the Brookie app the other day and had a look around. Very nice for creating invoice PDF\'s on save.

Bumped into the Brookie app the other day and had a look around. Very nice for creating invoice PDF's on save.

However, I get this error on creating a new invoice. I know that the error arises because there is开发者_C百科 no object and therefore it cannot have an attribute.

class InvoiceAdmin(admin.ModelAdmin):
    list_display = ('client', 'status', 'date', total_monetized, is_expired, pdf_invoice)
    list_filter = ('status', 'client')
    exclude = ('invoice_no',)
    ordering = ('id', )
    search_fields = ['client__company', ]
    readonly_fields = ()
    inlines = [ItemInline,]

class Media:
    js = ('http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js', 'brookie/js/brookie.js')

def get_readonly_fields(self, request, obj=None):
    readonly = super(InvoiceAdmin, self).get_readonly_fields(request, obj)

    # if the invoice is send you can no longer alter it
    if obj.status in br_settings.INVOICE_FINISH_STATUS:
        readonly = ('invoice_id', 'client', 'date', 'currency', 'tax', 'hourly_rate')

    return readonly

def save_model(self, request, obj, form, change):
    obj.save()
    if obj.status in br_settings.INVOICE_FINISH_STATUS:
        # Set the invoice id
        if not obj.invoice_no:
            invoice_list = Invoice.objects.filter(invoice_no__isnull=False).order_by('-invoice_no')
            try:
                invoice = invoice_list[0]
            except:
                # There are no numbered invoices
                invoice_no = getattr(br_settings, 'INVOICE_START_NUMBER', 1)
            else:
                invoice_no = invoice.invoice_no + 1
            obj.invoice_no = invoice_no
            obj.save()

        # Generate the pdf for this invoice
        context_dict = {'invoice': obj,
                        'client': obj.client,
                        'items': obj.items.all(),}

        generate_pdf(obj.invoice_id, context_dict, "brookie/invoice_%s_pdf.html" % obj.currency, save=True)

I've tried various ways to test the existance of the object before readonly fields. Readonly fields are returned if the invoice is in a state othehr than indevelopment (1)

How can I ignore the get_readonly_fields function if the object is new? I've also tried adding a default=1 to the model, testing for the existance of an obj before trying to access the status attibute to no sucess.

Thanks in advance

## EDIT ##

Traceback:
File "C:\Python26\lib\site-packages\django\core\handlers\base.py" in get_response
  100.                     response = callback(request, *callback_args, **callback_kwargs)
File "C:\Python26\lib\site-packages\django\contrib\admin\options.py" in wrapper
  239.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Python26\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  76.                     response = view_func(request, *args, **kwargs)
File "C:\Python26\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  69.         response = view_func(request, *args, **kwargs)
File "C:\Python26\lib\site-packages\django\contrib\admin\sites.py" in inner
  190.             return view(request, *args, **kwargs)
File "C:\Python26\lib\site-packages\django\utils\decorators.py" in _wrapper
  21.             return decorator(bound_func)(*args, **kwargs)
File "C:\Python26\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  76.                     response = view_func(request, *args, **kwargs)
File "C:\Python26\lib\site-packages\django\utils\decorators.py" in bound_func
  17.                 return func(self, *args2, **kwargs2)
File "C:\Python26\lib\site-packages\django\db\transaction.py" in _commit_on_success
  299.                     res = func(*args, **kw)
File "C:\Python26\lib\site-packages\django\contrib\admin\options.py" in add_view
  773.         ModelForm = self.get_form(request)
File "C:\Python26\lib\site-packages\django\contrib\admin\options.py" in get_form
  356.         exclude.extend(self.get_readonly_fields(request, obj))
File "C:\Sites\media\bread-and-pepper-django-brookie-a1a8102\brookie\admin.py" in get_readonly_fields
  124.         if obj.status in br_settings.INVOICE_FINISH_STATUS:

Exception Type: AttributeError at /admin/brookie/invoice/add/
Exception Value: 'NoneType' object has no attribute 'status'


The problem is that you're trying to evaluate the status attribute even in the case where obj is None, which is apparently an acceptable case.

To fix it, you could change this:

# if the invoice is send you can no longer alter it
if obj.status in br_settings.INVOICE_FINISH_STATUS:
    readonly = ('invoice_id', 'client', 'date', 'currency', 'tax', 'hourly_rate')

To this:

# if the invoice is send you can no longer alter it
if obj and obj.status in br_settings.INVOICE_FINISH_STATUS:
    readonly = ('invoice_id', 'client', 'date', 'currency', 'tax', 'hourly_rate')
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号