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/