Inside your create
method you should be able to access the arguments passed to the view rendering your endpoint at
self.context['view'].kwargs.get('member_id')
March 3, 2022 6 min read 1917
Navigate to an empty folder in your terminal and install Django and Django REST framework in your project with the commands below:
pip install django pip install django_rest_framework
Create a Django project called todo
with the following command:
django - admin startproject todo
Then, cd
into the new todo
folder and create a new app for your API:
django - admin startapp todo_api
Next, add rest_framework
and todo
to the INSTALLED_APPS
inside the todo/todo/settings.py
file:
# settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'todo_api' ]
Create a serializers.py
and urls.py
file in todo/todo_api
and add new files as configured in the directory structure below:
├── todo│├── __init__.py│├── settings.py│├── urls.py├── db.sqlite3├── manage.py└── todo_api├── admin.py├── serializers.py├── __init__.py├── models.py├── urls.py└── views.py
serializer.save() invokes an appropriate internal method based on arguments passed at initialization.,Very often, your model field names will differ from the required representation. Using the serializer field source parameter will let you handle this easily. Take a look at this example:,In some cases it is convenient to pass a value from outside of a serializer directly to its save() method. This method will take arguments that can be equated with serialized objects. Values passed this way won’t be validated. It may be used to force an override of the initial data. For example:,SerializerMethodField is a read only field that computes its value at request processing time, by calling a method on the serializer class it is attached to. Let’s say you have a model that stores datetime in a models.DateTimeField, but you want to use timestamp from epoch in your serialized representation:
class TagViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, mixins.RetrieveModelMixin, GenericViewSet): ""
" The following endpoints are fully provided by mixins: * List view * Create view "
""
queryset = Tag.objects.all() serializer_class = TagSerializer permission_classes = (permissions.IsAuthenticated, )
from django.conf.urls
import url, includefrom rest_framework.routers
import DefaultRouterapi_router = DefaultRouter() api_router.register(r 'tag', TagViewSet, 'tag') urlpatterns = [url(r '^v1/', include(api_router.urls, namespace = 'v1'))]
def retrieve(self, request, * args, ** kwargs): instance = self.get_object() serializer = ProfileSerializer(instance = instance) return Response(serializer.data)
def update(self, request, * args, ** kwargs): instance = self.get_object() serializer = ProfileSerializer(instance = instance, data = request.data) serializer.is_valid(raise_exception = True) serializer.save() return Response(serializer.data)
from rest_framework
import serializersclass TagSerializer(serializers.ModelSerializer): created = serializers.SerializerMethodField() class Meta: model = Tag fields = ('label', 'created') def get_created(self, obj): return round(obj.created.timestamp())
from rest_framework
import serializersclass TaskSerializer(serializers.ModelSerializer): job_type = serializers.CharField(source = 'task_type') class Meta: model = Task fields = ('job_type', )
owner_email = serializers.CharField(source = 'owner.email')
{
"bid": ["Bid is greater than your balance"]
}
serializer = EmailSerializer(data = request.data) serializer.is_valid(raise_exception = True) serializer.save(owner_id = request.user.id)
from rest_framework
import serializersclass SignupSerializer(serializers.ModelSerializer): password1 = serializers.CharField() password2 = serializers.CharField() def validate_password1(self, password1): if password1 != self.initial_data['password2']: raise serializers.ValidationError('Passwords do not match')
class CUDNestedMixin(object): @staticmethod def cud_nested(queryset: QuerySet, data: List[Dict], serializer: Type[Serializer], context: Dict): ""
" Logic for handling multiple updates, creates and deletes on nested resources :param queryset: queryset for objects existing in DB :param data: initial data to validate passed from higher level serializer to nested serializer :param serializer: nested serializer to use :param context: context passed from higher level serializer :return N/A "
""
updated_ids = list() for_create = list() for item in data: item_id = item.get('id') if item_id: instance = queryset.get(id = item_id) update_serializer = serializer(instance = instance, data = item, context = context) update_serializer.is_valid(raise_exception = True) update_serializer.save() updated_ids.append(instance.id)
else: for_create.append(item) delete_queryset = queryset.exclude(id__in = updated_ids) delete_queryset.delete() create_serializer = serializer(data = for_create, many = True, context = context) create_serializer.is_valid(raise_exception = True) create_serializer.save()
from rest_framework
import serializersclass AccountSerializer(serializers.ModelSerializer, CUDNestedMixin): phone_numbers = PhoneSerializer(many = True, source = 'phone_set', ) class Meta: model = User fields = ('first_name', 'last_name', 'phone_numbers') def update(self, instance, validated_data): self.cud_nested(queryset = instance.phone_set.all(), data = self.initial_data['phone_numbers'], serializer = PhoneSerializer, context = self.context)...
return instance