Django-rest-framework: Can not create non-model viewsets an register them to a model

Created on 22 Oct 2014  路  2Comments  路  Source: encode/django-rest-framework

I have the following database

 class Supplier(models.Model):
       projects = models.ManyToManyField(Project)

 class Project(models.Model):

and a viewsets for each:

  class SupplierViewSet(viewsets.GenericViewSet, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin):
          queryset = Supplier.objects.all()
          serializer_class = SupplierSerializer

 class ProjectViewSet(viewsets.ModelViewSet):
         queryset = Project.objects.all()
         serializer_class = ProjectSerializer

I want to be able to add connect a project and a supplier between each other. Since when i add a new connection i actually do more actions (make some calls to other servers) I do not want to write and maintain this on 2 Viewsets therefore I wanted to create just a normal non-model viewset that has a method to make that connection:

class SupplierProjectsViewSet(viewsets.ViewSet):
     """
      ViewSet that manages the many to many relationship between the Suppliers and Projects.
    """        
   def create(self, request, *args, **kwargs):
         supplier = Supplier.objects.get(pk=request.data['supplier_id'])
        project = Project.objects.get(pk=request.data['project_id'])

I register them with a router:
private_router = SimpleRouter()
private_router.register(r'suppliers', SupplierViewSet)
private_router.register(r'supplierprojects', SupplierProjectsViewSet)
private_router.register(r'projects', ProjectViewSet)

If i do this I get the following error
AssertionError: base_name argument not specified, and could not automatically determine the name from the viewset, as it does not have a .queryset attribute.

If i add: queryset = Supplier.objects.all() for example i get wrong urls names :+1:

 ^api/private/ ^supplierprojects/$ [name='supplier-list']
 ^api/private/ ^suppliers/$ [name='supplier-list']

If i change the queryset I also get other urls. What I would expect, it to be able to register a router without having defined the queryset param (non-model viewset) or accept more viewsets for the same model (I can see that happening, to have a public one and a private one with different functionality).

Most helpful comment

The right way to do that is to change the registration to add the base_name as indicated by the assertion error:

private_router.register(r'supplierprojects', SupplierProjectsViewSet, base_name='supplier-projects') 

Please note that this is a support question and should be asked on the mailing list or on irc.

All 2 comments

The right way to do that is to change the registration to add the base_name as indicated by the assertion error:

private_router.register(r'supplierprojects', SupplierProjectsViewSet, base_name='supplier-projects') 

Please note that this is a support question and should be asked on the mailing list or on irc.

thanks. I did not find that option and presumed it is a bug.

Was this page helpful?
0 / 5 - 0 ratings