Django-tastypie: Error: "class Meta has no attribute 'object_class'"

Created on 21 Jul 2016  ·  6Comments  ·  Source: django-tastypie/django-tastypie

Hi,

When I updated my tastypie from 13.3 to the head, trying to run my webapp throws this error:

Request Method: GET
Request URL: http://192.168.0.104:8888/accounts/login/?next=/dashboard/

Django Version: 1.8.8
Python Version: 2.7.12
Installed Applications:
('longerusernameandemail',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'tastypie',
 'myapp',
 'widget_tweaks',
 'corsheaders')
Installed Middleware:
('corsheaders.middleware.CorsMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')

Traceback:
File "/home/user/anaconda2/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  119.                 resolver_match = resolver.resolve(request.path_info)
File "/home/user/anaconda2/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
  365.             for pattern in self.url_patterns:
File "/home/user/anaconda2/lib/python2.7/site-packages/django/core/urlresolvers.py" in url_patterns
  401.         patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/home/user/anaconda2/lib/python2.7/site-packages/django/core/urlresolvers.py" in urlconf_module
  395.             self._urlconf_module = import_module(self.urlconf_name)
File "/home/user/anaconda2/lib/python2.7/importlib/__init__.py" in import_module
  37.     __import__(name)
File "/home/user/webserver/myapp/urls.py" in <module>
  7. from myapp.api import UserResource
File "/home/user/webserver/myapp/api.py" in <module>
  303. class MyResource(ModelResource):
File "/home/user/anaconda2/lib/python2.7/site-packages/tastypie/resources.py" in __new__
  1797.             if meta and meta.object_class:

Exception Type: AttributeError at /accounts/login/
Exception Value: class Meta has no attribute 'object_class'

If I switch back to version 13.3 (commit a71dd6e85e18ec38e978e904c0c7a91dee11043d) then it works fine.

Any idea what might be wrong?
Thanks

bug unconfirmed

Most helpful comment

@SeanHayes: I just ran into this same issue, because I was using an abstract base resource. Here's a reproduction:

class BaseResource(ModelResource):
    class Meta:
        authentication = DefaultAuthentication()

class FooResource(BaseResource):
    class Meta(BaseResource.Meta):
        resource_name = 'foo'
        queryset = Foo.objects.all()

class BarResource(BaseResource):
    class Meta(BaseResource.Meta):
        resource_name = 'bar'
        queryset = Bar.objects.all()

This fails with the same stack trace pasted by hashemian, at the line class BaseResource(ModelResource):, because the BaseResource doesn't have a queryset.

My workaround for now is to add object_class = None to BaseResource.Meta, then everything works.

I think the actual fix is to change resources.py line 1797 to if meta and getattr(meta, 'object_class'):

... or if it's desirable behavior for ModelResource subclasses to throw an error when queryset is not set, then that error could be more explicit. I don't think my BaseResource should fail, though, since then I'm not sure how to do what I'm trying to do here.

Thanks!

All 6 comments

Could you post your resources?

in my urls.py, I import tastypie.api.Api and then I import my resources one by one. It seems it fails as soon as it tries to load the first resource. For example this is one of the resources, but even if I comment out this one, it crashes on the next resource.

class MyResource(ModelResource):
    class Meta:
        queryset = MyModel.objects.all()
        fields = ['my_field']
        allowed_methods = ['get']
        resource_name = 'my_resource'
        authentication = BasicAuthentication()
        include_resource_uri = False

I just added regression tests but they failed to reproduce the error: 3e1f5527b698c7121d4c5434d073b08d364d31f2

Any more info you could provide? How close is your code sample to your actual code?

Thanks Sean for looking into this. The sample code is very much similar, and I basically just changed the names. I will check again on my end and try to see if there is any element that might be relevant and missing.

Closing, feel free to comment if you have more info.

@SeanHayes: I just ran into this same issue, because I was using an abstract base resource. Here's a reproduction:

class BaseResource(ModelResource):
    class Meta:
        authentication = DefaultAuthentication()

class FooResource(BaseResource):
    class Meta(BaseResource.Meta):
        resource_name = 'foo'
        queryset = Foo.objects.all()

class BarResource(BaseResource):
    class Meta(BaseResource.Meta):
        resource_name = 'bar'
        queryset = Bar.objects.all()

This fails with the same stack trace pasted by hashemian, at the line class BaseResource(ModelResource):, because the BaseResource doesn't have a queryset.

My workaround for now is to add object_class = None to BaseResource.Meta, then everything works.

I think the actual fix is to change resources.py line 1797 to if meta and getattr(meta, 'object_class'):

... or if it's desirable behavior for ModelResource subclasses to throw an error when queryset is not set, then that error could be more explicit. I don't think my BaseResource should fail, though, since then I'm not sure how to do what I'm trying to do here.

Thanks!

Was this page helpful?
0 / 5 - 0 ratings