aboutsummaryrefslogtreecommitdiffstats
path: root/src/rest/modelresource.py
diff options
context:
space:
mode:
authorTom Christie2011-01-17 17:34:58 +0000
committerTom Christie2011-01-17 17:34:58 +0000
commit99799032721a32220c32d4a74a950bdd07b13cb3 (patch)
tree8da016ed257181ba21804c947f18bde771476b08 /src/rest/modelresource.py
parentb0ce3f92c68b13d7f437a21bedcc95727e271860 (diff)
downloaddjango-rest-framework-99799032721a32220c32d4a74a950bdd07b13cb3.tar.bz2
Mostly improving documentation
Diffstat (limited to 'src/rest/modelresource.py')
-rw-r--r--src/rest/modelresource.py52
1 files changed, 50 insertions, 2 deletions
diff --git a/src/rest/modelresource.py b/src/rest/modelresource.py
index 39358d9b..6719a9ed 100644
--- a/src/rest/modelresource.py
+++ b/src/rest/modelresource.py
@@ -12,10 +12,38 @@ import re
class ModelResource(Resource):
+ """A specialized type of Resource, for RESTful resources that map directly to a Django Model.
+ Useful things this provides:
+
+ 0. Default input validation based on ModelForms.
+ 1. Nice serialization of returned Models and QuerySets.
+ 2. A default set of create/read/update/delete operations."""
+
+ # The model attribute refers to the Django Model which this Resource maps to.
+ # (The Model's class, rather than an instance of the Model)
model = None
+
+ # By default the set of returned fields will be the set of:
+ #
+ # 0. All the fields on the model, excluding 'id'.
+ # 1. All the properties on the model.
+ # 2. The absolute_url of the model, if a get_absolute_url method exists for the model.
+ #
+ # If you wish to override this behaviour,
+ # you should explicitly set the fields attribute on your class.
fields = None
+
+ # By default the form used with be a ModelForm for self.model
+ # If you wish to override this behaviour or provide a sub-classed ModelForm
+ # you should explicitly set the form attribute on your class.
+ form = None
+
+ # By default the set of input fields will be the same as the set of output fields
+ # If you wish to override this behaviour you should explicitly set the
+ # form_fields attribute on your class.
form_fields = None
+
def get_bound_form(self, data=None, is_response=False):
"""Return a form that may be used in validation and/or rendering an html emitter"""
if self.form:
@@ -25,7 +53,7 @@ class ModelResource(Resource):
class NewModelForm(ModelForm):
class Meta:
model = self.model
- fields = self.form_fields if self.form_fields else None #self.fields
+ fields = self.form_fields if self.form_fields else None
if data and not is_response:
return NewModelForm(data)
@@ -36,7 +64,27 @@ class ModelResource(Resource):
else:
return None
-
+
+
+ def cleanup_request(self, data, form_instance):
+ """Override cleanup_request to drop read-only fields from the input prior to validation.
+ This ensures that we don't error out with 'non-existent field' when these fields are supplied,
+ and allows for a pragmatic approach to resources which include read-only elements.
+
+ I would actually like to be strict and verify the value of correctness of the values in these fields,
+ although that gets tricky as it involves validating at the point that we get the model instance.
+
+ See here for another example of this approach:
+ http://fedoraproject.org/wiki/Cloud_APIs_REST_Style_Guide
+ https://www.redhat.com/archives/rest-practices/2010-April/thread.html#00041"""
+ read_only_fields = set(self.fields) - set(self.form_instance.fields)
+ input_fields = set(data.keys())
+
+ clean_data = {}
+ for key in input_fields - read_only_fields:
+ clean_data[key] = data[key]
+
+ return super(ModelResource, self).cleanup_request(clean_data, form_instance)
def cleanup_response(self, data):