0

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
Bibek
  • 21
  • 5
  • Without looking into DRF internals more deeply, I would guess that viewset registration within the router is keyed based on the model name, so when you have multiple registrations for viewsets with the same model, the last one encountered is the one registered (think of it as trying to assign two different values in a dict with the same key). I believe DRF has settings which allow you to override the actual detail URL at the viewset or view level. – DragonBobZ Dec 26 '22 at 18:46

1 Answers1

0

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/
  • Yeah ! I know that we need to add base_name. but I meant that why its generating same url: You told its because both viewsets are using same Model (Contact). -----------> Thank you For you Explanation. – Bibek Dec 26 '22 at 18:44
  • Np! Up vote and mark as the answer if it was helpful. – Sergio A. S. Dec 26 '22 at 19:06