I am trying to create a REST Api for my application.
urls.py in the application directory looks like this:
urlpatterns = [
url(
r'^professors/(?P<pk>[0-9]+)/reviews/$',
views.ProfessorReviewList.as_view(),
name = 'user-review-list',
)
]
serializers.py
class ProfessorSerializer(serializers.HyperlinkedModelSerializer):
reviews = serializers.HyperlinkedIdentityField(view_name='professor-review-list')
class Meta:
model = Professor
fields = (
'url', 'name', 'name_code', 'university',
'department', 'total_rating_points',
'number_of_reviews', 'rating', 'reviews',
)
class ReviewSerializer(serializers.HyperlinkedModelSerializer):
author = serializers.ReadOnlyField(source='author.username')
class Meta:
model = Review
fields = (
'url', 'author', 'professor',
'created', 'updated', 'rating', 'text'
)
And finally, my views.py looks like this:
class ProfessorReviewList(generics.ListCreateAPIView):
queryset = Review.objects.all()
serializer_class = ReviewSerializer
def get_queryset(self):
queryset = super(ProfessorReviewList, self).get_queryset()
return queryset.filter(professor__pk=self.kwargs.get('pk'))
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsAuthorOrReadOnly,)
def perform_create(self, serializer):
# The request user is set as author automatically.
serializer.save(author=self.request.user)
What I am trying to do is get a list of all the reviews for one particular professor when I go to the URL. I also want to allow users to add a new review at this end-point if they want to. Everything works nicely, but I want a system where the user does not have to choose the professor when creating a review.
Lets say I go to /professors/1/reviews/, a list of all the reviews for the professor with pk=1 is obtained. Now, if the user adds a new review, the professor is automatically set to the professor with pk=1. The user does not get to choose. At /professors/2/reviews/, the professor field for the review is automatically set to the professor with pk=2 and so on and so on.
How can I do this? Thanks for any help.
perform_create. perform create method is used to add extra information when creating a new object. perform_create() method will not execute if you override create() method.
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.
ModelViewSet. The ModelViewSet class inherits from GenericAPIView and includes implementations for various actions, by mixing in the behavior of the various mixin classes. The actions provided by the ModelViewSet class are .list() , .retrieve() , .create() , .update() , .partial_update() , and .destroy() .
Writing mixins for Django Class Based Viewsmixins override dispatch if they need to check if user if logged in, has permission. This is one of the first methods called and view determines which request method (get, post etc) is used. mixins override get_context_data() to add new data to context.
You should simply add the professor as you did with the author:
serializer.save(
author=self.request.user,
professor_id=self.kwargs.get('pk'),
)
Note that in order to avoid to pull the professor from the DB, I set the FK explicitly instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With