Home > Net >  Why django-rest-framework is generating same api url for two views (both views having same queryset)
Why django-rest-framework is generating same api url for two views (both views having same queryset)

Time:12-27

My Project Configuration is this. This is realated to Contact Form. Here I have two approach: Customer from frontend can only post (i.e. send message) and admin can only retrieve and list the contacts.

Models.py

class Contact(models.Model):
        full_name = models.CharField(max_length=100)
        email =  models.EmailField()
        phone_no = models.CharField(max_length=10, validators=[validate_phone_no])
        message = models.TextField()
        created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
    
        def __str__(self):
        return self.email

serializers.py

    class ContactSerializer(serializers.ModelSerializer):
        class Meta: 
            model = Contact
            fields = [
                'full_name',
                'email',
                'phone_no',
                'message',
            ]

Views.py

class ContactViewset(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]
    queryset = Contact.objects.all()
    search_fields = []
    ordering_fields = []
    ordering = []
    http_method_names = ["options", "head", "get"]

    serializer_class = ContactSerializer


class CustomerContactViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    queryset = Contact.objects.all()
    http_method_names = ['post']

    serializer_class = ContactSerializer

urls.py

router.register("contacts-detail", ContactViewset)
router.register("contact-form", CustomerContactViewSet)

My question is: Why DRF is generating the same url for both views although I have given different names for both:

'contact-form'----> for posting and 
'contact-detail'--------> for listing the contacts 

Both views are pointing to same Model - Is this the Reason?

Click Here to see generated api url

See last urls are same: and redirecting to "contact-form". and I know I can give base_name to seperate both.

But I wanted to know the mechanism behind generating same url:

If anyone could explain this? Clearly

CodePudding user response:

The problem is with the way you have defined the router.register calls in your urls.py file.

The first argument of the router.register function is the base name for the viewset. This base name is used to generate the URL patterns for the viewset. If you use the same base name for multiple viewsets, then the router will generate the same URL pattern for both viewsets.

For example, in your code you have defined the following lines:

router.register("contacts-detail", ContactViewset) router.register("contact-form", CustomerContactViewSet)

Here, you have used the base name "contacts-detail" for the ContactViewset and the base name "contact-form" for the CustomerContactViewSet. This will result in two different URL patterns being generated:

/contacts-detail/
/contact-form/

However, since both viewsets are using the same model (Contact), the router will generate the same set of URL patterns for both viewsets. This is why you are seeing the same URL patterns for both viewsets in your API.

To fix this problem, you can use different base names for the two viewsets. For example, you could use "contacts" for the ContactViewset and "customer-contacts" for the CustomerContactViewSet. This would result in the following URL patterns being generated:

/contacts/
/customer-contacts/
  • Related