Skip to content

Commit 127ad5a

Browse files
authored
Add views (#11)
* init rest api for views * init views for thee frameworks * end add views
1 parent e9ae9eb commit 127ad5a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+3263
-421
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ pip install python-rest-framework
2828
git clone [email protected]:nxexox/python-rest-framework.git
2929
```
3030

31+
## Versions for Python Web Frameworks
32+
33+
```bash
34+
pip install python-rest-framework[flask] # For Flask framework
35+
pip install python-rest-framework[aiohttp] # For AioHttp framework
36+
pip install python-rest-framework[sanic] # For Sanic framework
37+
```
38+
3139
## Example
3240

3341
For example, we will serialize the data from the request object.

docs/api-guid/fields.md

Lines changed: 112 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Serializer fields handle converting between primitive values and internal dataty
1212

1313
Each serializer field class constructor takes at least these arguments. Some Field classes take additional, field-specific arguments, but the following should always be accepted:
1414

15-
### - `required`
15+
###`required`
1616

1717
Normally an error will be raised if a field is not supplied during deserialization.
1818
Set to false if this field is not required to be present during deserialization.
@@ -21,7 +21,7 @@ Setting this to `False` also allows the object attribute or dictionary key to be
2121

2222
Defaults to `True`.
2323

24-
### - `default`
24+
###`default`
2525

2626
If set, this gives the default value that will be used for the field if no input value is supplied. If not set the default behaviour is to not populate the attribute at all.
2727

@@ -31,31 +31,31 @@ When serializing the instance, default will be used if the the object attribute
3131

3232
Note that setting a `default` value implies that the field is not required. Enabling the arguments of the `default` keyword will set the` required` to `False`.
3333

34-
### - `label`
34+
###`label`
3535

3636
A short text string that may be used as the name of the field in HTML form fields or other descriptive elements.
3737

38-
### - `validators`
38+
###`validators`
3939

4040
A list of validator functions which should be applied to the incoming field input, and which either raise a validation error or simply return. Validator functions should raise `serializers.ValidationError`.
4141

42-
### - `error_messages`
42+
###`error_messages`
4343

4444
A dictionary of error codes to error messages.
4545

4646
---
4747

4848
# Fields
4949

50-
## - BooleanField
50+
## BooleanField
5151

5252
When using HTML encoded form input be aware that omitting a value will always be treated as setting a field to `False`, even if it has a `default=True` option specified. This is because HTML checkbox inputs represent the unchecked state by omitting the value, so REST framework treats omission as if it is an empty checkbox input.
5353

5454
**Signature:** `BooleanField()`
5555

5656
---
5757

58-
## - BooleanNullField
58+
## BooleanNullField
5959

6060
A boolean representation that also accepts `None` as a valid value.
6161

@@ -65,7 +65,7 @@ When using HTML encoded form input be aware that omitting a value will always be
6565

6666
---
6767

68-
## - CharField
68+
## CharField
6969

7070
A text representation. Optionally validates the text to be shorter than `max_length` and longer than `min_length`.
7171

@@ -78,7 +78,7 @@ A text representation. Optionally validates the text to be shorter than `max_len
7878

7979
---
8080

81-
## - IntegerField
81+
## IntegerField
8282

8383
An integer representation.
8484

@@ -89,7 +89,7 @@ An integer representation.
8989

9090
---
9191

92-
## - FloatField
92+
## FloatField
9393

9494
A floating point representation.
9595

@@ -102,7 +102,7 @@ A floating point representation.
102102

103103
# Date and time fields
104104

105-
## - DateTimeField
105+
## DateTimeField
106106

107107
A date and time representation.
108108

@@ -117,7 +117,7 @@ Format strings may either be [Python strftime formats][strftime] which explicitl
117117

118118
When a value of `None` is used for the format `datetime` objects will be returned by `to_representation` and the final output representation will determined by the renderer class.
119119

120-
## - DateField
120+
## DateField
121121

122122
A date representation.
123123

@@ -130,7 +130,7 @@ A date representation.
130130

131131
Format strings may either be [Python strftime formats][strftime] which explicitly specify the format, or the special string `'iso-8601'`, which indicates that [ISO 8601][iso8601] style dates should be used. (eg `'2013-01-29'`)
132132

133-
## - TimeField
133+
## TimeField
134134

135135
A time representation.
136136

@@ -147,7 +147,7 @@ Format strings may either be [Python strftime formats][strftime] which explicitl
147147

148148
# Composite fields
149149

150-
## - ListField
150+
## ListField
151151

152152
A field class that validates a list of objects.
153153

@@ -159,25 +159,25 @@ A field class that validates a list of objects.
159159
- `allow_blank` - If set to` True`, an empty array should be considered valid. If set to `False`, an empty array is considered invalid and causes a validation error. The default is `False`.
160160

161161
For example, to validate a list of integers you might use something like the following:
162-
163-
scores = serializers.ListField(
164-
child=serializers.IntegerField(min_value=0, max_value=100)
165-
)
166-
162+
```python
163+
scores = serializers.ListField(
164+
child=serializers.IntegerField(min_value=0, max_value=100)
165+
)
166+
```
167167
The `ListField` class also supports a declarative style that allows you to write reusable list field classes.
168-
169-
class StringListField(serializers.ListField):
170-
child = serializers.CharField()
171-
168+
```python
169+
class StringListField(serializers.ListField):
170+
child = serializers.CharField()
171+
```
172172
We can now reuse our custom `StringListField` class throughout our application, without having to provide a `child` argument to it.
173173

174-
## - JSONField
174+
## JSONField
175175

176176
A field class that validates that the incoming data structure consists of valid JSON primitives. In its alternate binary mode, it will represent and validate JSON-encoded binary strings.
177177

178178
**Signature**: `JSONField()`
179179

180-
## - DictField
180+
## DictField
181181

182182
A field class that validates a dictionary of objects. The keys in `DictField` are always assumed to be string values.
183183

@@ -186,19 +186,19 @@ A field class that validates a dictionary of objects. The keys in `DictField` ar
186186
- `child` - A field instance that should be used for validating the values in the dictionary. If this argument is not provided then values in the mapping will not be validated.
187187

188188
For example, to create a field that validates a mapping of strings to strings, you would write something like this:
189-
190-
document = DictField(child=CharField())
191-
189+
```python
190+
document = DictField(child=CharField())
191+
```
192192
You can also use the declarative style, as with `ListField`. For example:
193-
194-
class DocumentField(DictField):
195-
child = CharField()
196-
193+
```python
194+
class DocumentField(DictField):
195+
child = CharField()
196+
```
197197
---
198198

199199
# Miscellaneous fields
200200

201-
## - SerializerMethodField
201+
## SerializerMethodField
202202

203203
It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object.
204204

@@ -208,27 +208,27 @@ It gets its value by calling a method on the serializer class it is attached to.
208208
- `method_name_pop` - The name of the method on the calling serializer during validation data. If not included this defaults to `pop_<field_name>`.
209209

210210
The serializer method referred to by the `method_name_get` argument should accept a single argument (in addition to `self`), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:
211+
```python
212+
from datetime.datetime import now
213+
from rest_framework import serializers
211214

212-
from datetime.datetime import now
213-
from rest_framework import serializers
214-
215-
class UserSerializer(serializers.Serializer):
216-
days_since_joined = serializers.SerializerMethodField()
217-
218-
def get_days_since_joined(self, obj):
219-
return (now() - obj.date_joined).days
215+
class UserSerializer(serializers.Serializer):
216+
days_since_joined = serializers.SerializerMethodField()
220217

218+
def get_days_since_joined(self, obj):
219+
return (now() - obj.date_joined).days
220+
```
221221
The serializer method referenced by the `method_name_pop` argument must take one argument (in addition to` self`), which is the value to process and validate. It must return whatever you want to include in the validated view of the data. For example:
222+
```python
223+
from datetime.datetime import now
224+
from rest_framework import serializers
222225

223-
from datetime.datetime import now
224-
from rest_framework import serializers
225-
226-
class UserSerializer(serializers.Serializer):
227-
rgb = serializers.SerializerMethodField()
228-
229-
def pop_rgb(self, data):
230-
return data.split(';')[1:3]
226+
class UserSerializer(serializers.Serializer):
227+
rgb = serializers.SerializerMethodField()
231228

229+
def pop_rgb(self, data):
230+
return data.split(';')[1:3]
231+
```
232232
---
233233

234234
# Custom fields
@@ -246,91 +246,91 @@ The `to_internal_value()` method is called to restore a primitive datatype into
246246
### A Basic Custom Field
247247

248248
Let's look at an example of serializing a class that represents an RGB color value:
249+
```python
250+
class Color(object):
251+
"""
252+
A color represented in the RGB colorspace.
249253
250-
class Color(object):
251-
"""
252-
A color represented in the RGB colorspace.
253-
254-
"""
255-
def __init__(self, red, green, blue):
256-
assert(red >= 0 and green >= 0 and blue >= 0)
257-
assert(red < 256 and green < 256 and blue < 256)
258-
self.red, self.green, self.blue = red, green, blue
259-
260-
class ColorField(serializers.Field):
261-
"""
262-
Color objects are serialized into 'rgb(#, #, #)' notation.
254+
"""
255+
def __init__(self, red, green, blue):
256+
assert(red >= 0 and green >= 0 and blue >= 0)
257+
assert(red < 256 and green < 256 and blue < 256)
258+
self.red, self.green, self.blue = red, green, blue
263259

264-
"""
265-
def to_representation(self, value):
266-
return "rgb(%d, %d, %d)" % (value.red, value.green, value.blue)
260+
class ColorField(serializers.Field):
261+
"""
262+
Color objects are serialized into 'rgb(#, #, #)' notation.
267263
268-
def to_internal_value(self, data):
269-
data = data.strip('rgb(').rstrip(')')
270-
red, green, blue = [int(col) for col in data.split(',')]
271-
return Color(red, green, blue)
264+
"""
265+
def to_representation(self, value):
266+
return "rgb(%d, %d, %d)" % (value.red, value.green, value.blue)
272267

268+
def to_internal_value(self, data):
269+
data = data.strip('rgb(').rstrip(')')
270+
red, green, blue = [int(col) for col in data.split(',')]
271+
return Color(red, green, blue)
272+
```
273273
By default field values are treated as mapping to an attribute on the object or key Mapping collection. If you need to customize how the field value is accessed and set you need to override `.get_attribute()`.
274274

275275
As an example, let's create a field that can be used to represent the class name of the object being serialized:
276+
```python
277+
class ClassNameField(serializers.Field):
278+
def get_attribute(self, instance):
279+
# We pass the object instance onto `to_representation`,
280+
# not just the field attribute.
281+
return instance
282+
283+
def to_representation(self, value):
284+
"""
285+
Serialize the value's class name.
276286
277-
class ClassNameField(serializers.Field):
278-
def get_attribute(self, instance):
279-
# We pass the object instance onto `to_representation`,
280-
# not just the field attribute.
281-
return instance
282-
283-
def to_representation(self, value):
284-
"""
285-
Serialize the value's class name.
286-
287-
"""
288-
return value.__class__.__name__
289-
287+
"""
288+
return value.__class__.__name__
289+
```
290290
### Raising validation errors
291291

292292
Our `ColorField` class above currently does not perform any data validation.
293293
To indicate invalid data, we should raise a `serializers.ValidationError`, like so:
294+
```python
295+
def to_internal_value(self, data):
296+
if not isinstance(data, six.text_type):
297+
msg = 'Incorrect type. Expected a string, but got %s'
298+
raise ValidationError(msg % type(data).__name__)
294299

295-
def to_internal_value(self, data):
296-
if not isinstance(data, six.text_type):
297-
msg = 'Incorrect type. Expected a string, but got %s'
298-
raise ValidationError(msg % type(data).__name__)
300+
if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
301+
raise ValidationError('Incorrect format. Expected `rgb(#,#,#)`.')
299302

300-
if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
301-
raise ValidationError('Incorrect format. Expected `rgb(#,#,#)`.')
303+
data = data.strip('rgb(').rstrip(')')
304+
red, green, blue = [int(col) for col in data.split(',')]
302305

303-
data = data.strip('rgb(').rstrip(')')
304-
red, green, blue = [int(col) for col in data.split(',')]
305-
306-
if any([col > 255 or col < 0 for col in (red, green, blue)]):
307-
raise ValidationError('Value out of range. Must be between 0 and 255.')
308-
309-
return Color(red, green, blue)
306+
if any([col > 255 or col < 0 for col in (red, green, blue)]):
307+
raise ValidationError('Value out of range. Must be between 0 and 255.')
310308

309+
return Color(red, green, blue)
310+
```
311311
The `.fail()` method is a shortcut for raising `ValidationError` that takes a message string from the `error_messages` dictionary. For example:
312+
```python
313+
default_error_messages = {
314+
'incorrect_type': 'Incorrect type. Expected a string, but got {input_type}',
315+
'incorrect_format': 'Incorrect format. Expected `rgb(#,#,#)`.',
316+
'out_of_range': 'Value out of range. Must be between 0 and 255.'
317+
}
312318

313-
default_error_messages = {
314-
'incorrect_type': 'Incorrect type. Expected a string, but got {input_type}',
315-
'incorrect_format': 'Incorrect format. Expected `rgb(#,#,#)`.',
316-
'out_of_range': 'Value out of range. Must be between 0 and 255.'
317-
}
319+
def to_internal_value(self, data):
320+
if not isinstance(data, six.text_type):
321+
self.fail('incorrect_type', input_type=type(data).__name__)
318322

319-
def to_internal_value(self, data):
320-
if not isinstance(data, six.text_type):
321-
self.fail('incorrect_type', input_type=type(data).__name__)
323+
if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
324+
self.fail('incorrect_format')
322325

323-
if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
324-
self.fail('incorrect_format')
326+
data = data.strip('rgb(').rstrip(')')
327+
red, green, blue = [int(col) for col in data.split(',')]
325328

326-
data = data.strip('rgb(').rstrip(')')
327-
red, green, blue = [int(col) for col in data.split(',')]
328-
329-
if any([col > 255 or col < 0 for col in (red, green, blue)]):
330-
self.fail('out_of_range')
331-
332-
return Color(red, green, blue)
329+
if any([col > 255 or col < 0 for col in (red, green, blue)]):
330+
self.fail('out_of_range')
333331

332+
return Color(red, green, blue)
333+
```
334334
This style keeps your error messages cleaner and more separated from your code, and should be preferred.
335335

336336
[iso8601]: https://www.w3.org/TR/NOTE-datetime

0 commit comments

Comments
 (0)