-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserializers.py
More file actions
146 lines (118 loc) · 5.92 KB
/
Copy pathserializers.py
File metadata and controls
146 lines (118 loc) · 5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
from dataclasses import fields
from decimal import Decimal
from unittest.util import _MAX_LENGTH
from rest_framework import serializers
from rest_framework.validators import UniqueValidator , UniqueTogetherValidator
import bleach
# from Learn_APIs.DRF_RestroAPI.LemonRestro.LemonAPI.views import menu_items
from .models import MenuItem , Category
#---------------------------------------------------------------------------------------------------#
# serializers for class based views
#---------------------------------------------------------------------------------------------------#
class MenuItemSerializer(serializers.ModelSerializer):
class Meta:
model = MenuItem
fields = ['id', 'title', 'price', 'inventory']
class MenuItemSerializer1(serializers.ModelSerializer):
id = serializers.IntegerField()
title = serializers.CharField()
class Meta:
model = MenuItem
fields = ['id', 'title', 'price']
#---------------------------------------------------------------------------------------------------#
# Model Serializer for function based views , for @api_view() decorator
#---------------------------------------------------------------------------------------------------#
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['id', 'slug','title']
###------------------------------------------------------------------------###
# for menu items @api_view() decorator
class MenuItemSerializer2(serializers.ModelSerializer):
# change the name of the field
stock = serializers.IntegerField(source='inventory')
# after method add field
total_price = serializers.SerializerMethodField(method_name='calculate_tax')
#-------------------------------------------------------------------------------#
# for string related filed
# category=serializers.StringRelatedField()
# directly using
#category = CategorySerializer()
#-------------------------------------------------------------------------------#
# for the HyperlinkRelatedField:
#-------------------------------------------------------------------------------#
# category = serializers.HyperlinkedRelatedField(
# queryset = Category.objects.all(),
# view_name = 'category-detail'
# ) # add the context in the menu-items function
#-------------------------------------------------------------------------------#
# for Deserilization
category = CategorySerializer(read_only = True)
category_id = serializers.IntegerField(write_only=True)
#-------------------------------------------------------------------------------#
#-------------------------------------------------------------------------------#
# Using the Bleach for validate_field
#-------------------------------------------------------------------------------#
def validate_title(self, value):
return bleach.clean(value)
# # Using the validate() method
# def validate(self,attrs):
# attrs['price'] =bleach.clean(attrs['price'])
# if(attrs['price'])<Decimal('10'):
# raise serializers.ValidationError("The Price Must be at least $10")
# # the bleach can be used to validate the below fileds for sql injection
# attrs['title'] = bleach.clean(attrs['title'])
# attrs['price'] = bleach.clean(attrs['price'])
# # limit = request.GET.get('limit')
# # MenuItem.objects.raw('SELECT * FROM LittleLemonAPI_menuitem LIMIT %s', [limit])
#-------------------------------------------------------------------------------#
# # Method:3 Using validate_field() method
# def validate_price(self, value):
# if value < Decimal('10'):
# raise serializers.ValidationError('The Price Must be at least $10')
# def validate_stock(self, value):
# if value <0:
# raise serializers.ValidationError('The Stock Must be at least 0')
# Method 4 : Using the validate() method
def vlaidate(self, attrs):
if attrs['price'] < Decimal('10'):
raise serializers.ValidationError('The Price Must be at least $10')
if attrs['stock'] <0:
raise serializers.ValidationError('The Stock Must be at least 0')
class Meta:
model = MenuItem
fields = ['id', 'title', 'price', 'stock', 'total_price','category', 'category_id']
# depth=1 # for the nested serializer
# API Data Validation:
#Method:1. Using the Keyword Arguments in the Meta class
# extra_kwargs = {
# 'price': {'min_value': Decimal('10')},
# 'stock' : {'source':'inventory', 'min_value':0}
# }
# #1.1 UniqueValidator using the extra_kwargs
# extra_kwargs= {
# 'title':{
# 'validators':[UniqueValidator(queryset=MenuItem.objects.all())]
# }
# }
# # Or using above the meta class
# # title = serializers.CharField(validators=[UniqueValidator(queryset=MenuItem.objects.all()),message='Ttile Must be Unique'])
# #1.2 UniqueTogetherValidator
# validators = [UniqueTogetherValidator(
# queryset=MenuItem.objects.all(),
# fields=['title','price']),
# ]
def calculate_tax(self, product:MenuItem):
return product.price * Decimal('1.1')
#-------------------------------------------------------------------------------#
# MenuItemSerializer extends the serializers.HyperlinkedModelSerializer class instead
#-------------------------------------------------------------------------------#
# class MenuItemSerializer2(serializers.HyperlinkedModelSerializer):
# stock = serializers.IntegerField(source='inventory')
# total_price = serializers.SerializerMethodField(method_name='calculate_tax')
# class Meta:
# model = MenuItem
# fields = ['id', 'title', 'price', 'stock', 'total_price','category']
# # depth=1
# def calculate_tax(self, product:MenuItem):
# return product.price * Decimal('1.1')