drf Flashcards
what a router does is
generates the url patterns for the viewsets you register to it, and gives you an object to throw into urls.py
goes in stub folder
project_name/project_name/router.py
from rest_framework import routers
from app_name.api.viewsets import *
router = routers.DefaultRouter()
router.register(r’model_name’, RatingViewSet, ‘model_name’)
a viewset is
a class in which you define the actions and serializers you want to use, or use ModelViewSet to just set the serializer and and queryset and all the functions from the router will be injected.
note: when setting the queryset, dont use an underscore query_set.
in app_name/api/viewsets.py
from app_name.models import ModelName
from .serializers import ModelnameSerializer
from rest_framework import viewsets
from rest_framework import permissions
class ModelNameViewSet(viewsets.ModelViewSet): permission_classes = (permissions.IsAuthenticatedOrReadOnly,) queryset = Modelname.objects.all() serializer_class = ModelNameSerializer
to use request.user in the viewset, type
Overwrite the queryset property with a custom function
class ModelNameViewSet(viewsets.ModelViewSet): permission_classes = (permissions.IsAuthenticatedOrReadOnly,) serializer_class = ModelNameSerializer
def get_queryset(self): user = self.request.user return ModelName.objects.filter(user=user)
a serializer is
a class that defines how to convert an object to a key, value dictionary. It’s a lot like a form, and can perform validations
class ModelNameSerializer(serializers.Serializer): field_1 = serializers.EmailField(required=False)#makes optional field_2 = serializers.CharField(max_length=200) def validate_field_1(self, field_value): if field_value < 1: raise serializers.ValidationError("string") return field_value
or to skip the field definitions and use the defaults from the model
from rest_framework import serializers
from app_name.models import ModelName
class ModelNameSerializer(serializers.ModelSerializer): class Meta: model = ModelName fields = ('field_1', 'field_2',) # or just "\_\_all\_\_"
To add a custom computed field to a serializer
add a function to your model
then add to serializer
class ModelNameSerializer(serializers.Serializer): new_function = serializers.ReadOnlyField() class Meta: model = ModelName fields = ('new_function',)
or maybe for foreign keys
class ModelNameSerializer(serializers.ModelSerializer): custom_field = serializers.ReadOnlyField(source="foreign_key_field.field") class Meta: model = ModelName fields = ('field_1', 'custom_field',)
good tutorial
https://www.youtube.com/watch?v=riZYgLOYq4g&t=562s
to have nested objects inside a serializer
https://stackoverflow.com/questions/14938895/serializer-dealing-with-nested-objects
and to have them nested but with a reverse relationship list of objects
https://stackoverflow.com/questions/14573102/how-do-i-include-related-model-fields-using-django-rest-framework
to create a serializer that loads in related objects (that have a forward relationship, aka, they contain the field=models.ForeignKey()) as nested dictionaries, type
class ModelNameSerializer(serializers.ModelSerializer): class Meta: model = ModelName depth = 1
to serialize a related foreign key object
name the field in the serializer the same as the foreign key field name, and set the value to the serializer you want to use for the related element.
class RelatedModelSerializer(serializers.ModelSerializer): class Meta: model = RelatedModel fields = ('field_1', 'field_2')
class ProductSerializer(serializers.ModelSerializer): related_field_name = RelatedModelSerializer()
class Meta: model = Product fields = ('field_1', 'field_2', 'related_field_name')
notes
from rest_framework import routers
from noot.api.viewsets import *
router = routers.DefaultRouter() # router.register(r'ratings', RatingViewSet, 'ratings')
# this generates a list of url() pattern objects and passes them into the urls.py (just creates /object_name/ and /object_name/id/ because the actions are chosen with http method) # the first argument is the prefix of the url pattern definition/namespace # The router uses the queryset defined in the viewset to determine the base_name # base_name is the prefix it will use for names in the url(..., name='string') definitions. Becomes url(..., name='prefix_base_name_string') # rest of the name will be the filled with the generated view types: base_name-list, base_name-detail from the viewset # using a routers prevents you from needing to write your own url patterns # https://stackoverflow.com/questions/46053922/delete-method-on-django-rest-framework-modelviewset # To hit the different actions, you need to use the right http method. list:get, create:post, retrieve:get, update:put, partial_update:patch, destroy:delete. # router makes these automatically
url(r'^api/', include(router.urls)), # this allows you to add additional urls by registering them to router
from rest_framework import serializers
from noot.models import Rating
# class RatingSerializer(serializers.ModelSerializer): # class Meta: # model = Rating # fields = ('noot', 'rating', 'user', 'pk')
from noot.models import Rating # from .serializers import RatingSerializer from rest_framework import viewsets
# class RatingViewSet(viewsets.ModelViewSet): # queryset = Rating.objects.all() # serializer_class = RatingSerializer
# the attributes set in this ModelView class are just there to be used by all the later functions # many of these functions are invisible because they are inherited from parent class # if you use a modelviewset instead of viewset, it adds the methods the router generated routes for: list, create, retrieve, update, partial_update, delete # otherwise you need to define these functions yourself
To serialize a qs and have a nested field thats a reverse relationship
class ModelNameSerializer(serializers.ModelSerializer): model_name_set = ReverseRelatedModelNameSerializer(read_only=True, many=True, source='model_name_set') class Meta: model = Cart depth = 1 fields = ( 'field_1', 'field_2', 'model_name_set', )
To make a user pass a test or otherwise redirect for function based views
https://stackoverflow.com/questions/8082670/django-user-passes-test-decorator
To create custom rest framework permission
https://www.youtube.com/watch?v=-0c88d24qzM
To add a function decorator to a class based views methods
https://stackoverflow.com/questions/8082670/django-user-passes-test-decorator
under the hood, the generated code for the list function in a viewset is
def list(self, request); queryset = ModelName.objects.all() serializer = ModelNameSerializer(queryset, many=True) return Response(serializer.data)