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).
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.
Most helpful comment
The right way to do that is to change the registration to add the
base_nameas indicated by the assertion error:Please note that this is a support question and should be asked on the mailing list or on irc.