3

I am trying to use django-rest-framework-mongoengine to build a webservice using Django and mongodb.

I have an error when I include a url that lists my objects of type Document.

My model file is

class Job(Document):
    title = StringField(required=True)
    state = StringField(required=True)

My view is

class JobViewSet(GenericAPIView):
    queryset = Job.objects.all()
    serializer_class = JobSerializer

My url file is

router = routers.MongoSimpleRouter()
router.register(r'jobs', views.JobViewSet)

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

my serializer is

class JobSerializer(DocumentSerializer):
    class Meta:
        model = Job
        fields = ('title', 'state')

I get the following error when I do runserver

`base_name` argument not specified, and could not automatically determine the name from the viewset, as it does not have a `.model` attribute.

I tried different view type but all the same error. Any help is greatly appreciated....

I am using

python 2.7.9
Django==1.7.7 
django-rest-framework-mongoengine==2.0.2    
mongoengine==0.9.0

here is the full stack

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/

Django Version: 1.7.7
Python Version: 2.7.9
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'romeo',
 'mongoengine.django.mongo_auth',
 'jobs',
 'rest_framework',
 'rest_framework_mongoengine')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  98.                 resolver_match = resolver.resolve(request.path_info)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
  343.             for pattern in self.url_patterns:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/urlresolvers.py" in url_patterns
  372.         patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/urlresolvers.py" in urlconf_module
  366.             self._urlconf_module = import_module(self.urlconf_name)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py" in import_module
  37.     __import__(name)
File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_imps/_pydev_pluginbase.py" in plugin_import
  452.                                    fromlist, level)
File "/Users/amer/Workspace/Repository/romeo/romeo/urls.py" in <module>
  6. router.register(r'jobs', views.JobViewSet)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/rest_framework/routers.py" in register
  60.             base_name = self.get_default_base_name(viewset)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/rest_framework_mongoengine/routers.py" in get_default_base_name
  11.         assert model_cls, '`base_name` argument not specified, and could ' \

Exception Type: AssertionError at /
Exception Value: `base_name` argument not specified, and could not automatically determine the name from the viewset, as it does not have a `.model` attribute.
Amer
  • 335
  • 5
  • 16

2 Answers2

4

You need to add the base_name param to make it work:

router = routers.MongoSimpleRouter()
router.register(r'jobs', views.JobViewSet, 'job-view')

I try this (from Geo Jacob answer) but it doesn't work:

router.register(r'jobs', views.JobViewSet, base_name='job-view')

Note: note the difference between base_name='job-view' and 'job-view'

Giovanni Benussi
  • 3,102
  • 2
  • 28
  • 30
  • 1
    That's a very basic python problem but one forgets about language issues for a moment and starts to blame routers, views, etc. Thanks for the note! – chachan Feb 12 '17 at 22:43
2

Try to add a base_name in router register.

router = routers.MongoSimpleRouter()
router.register(r'jobs', views.JobViewSet, base_name='job-view')
Geo Jacob
  • 5,909
  • 1
  • 36
  • 43
  • I tried that and it didn't work. I tried base_name='JobViewSet'. I am getting a page not found error. Using the URLconf defined in romeo.urls, Django tried these URL patterns, in this order: ^api-auth/ The current URL, , didn't match any of these. It is like the registration is not happening any more – Amer Apr 02 '15 at 07:19
  • try to inherit from viewsets.ModelViewset. And if not working, paste your error and complete code. – Geo Jacob Apr 02 '15 at 07:50
  • I did and that didn't work. I traced the code and when I call router.register(r'jobs', views.JobViewSet, base_name='job') it recognizes the base name and it executes self.registry.append((prefix, viewset, base_name)) which is inside router.register. the issue is that for some reason it never adds the URLs for the job. I am not sure how it determines how to get the urls for that view/class. The error now is Page not found as it can't find /jobs/ url – Amer Apr 02 '15 at 08:04
  • OK so I made the following changes I am using router = routers.MongoSimpleRouter() and the view is of type rest_framework_mongoengine.viewsets.ModelViewSet and this seems to work. At least it adds the URLs to my router but now I get the following error 'QuerySet' object has no attribute 'model' – Amer Apr 02 '15 at 08:30
  • btw the base_name should probably be set to the class name to get a better url.. i used base_name='Job' – Amer Apr 02 '15 at 08:34
  • Adding 'base_name' while registering url worked for me. I think Django >1.8 need to mention base_name. – vinayakumarnk Nov 20 '17 at 10:26