I am planning to make generic CRUD using django-piston. One of my sample code has following
class TaskHandler(BaseHandler):
allowed_methods = ('GET','POST',)
model = Task
def read(self, name=None):
return self.model.objects.all()
def create(self, request, *args, **kwargs):
if not self.has_model():
return rc.NOT_IMPLEMENTED
attrs = self.flatten_dict(request.POST)
if attrs.has_key('data'):
# rest.POST.get('data') has csrfmiddlewaretoken as a hiddenfield
# i need to exclude it from post as my ORM is giving error message
ext_posted_data = simplejson.loads(request.POST.get('data'))
attrs = self.flatten_dict(ext_posted_data)
try:
inst = self.model.objects.get(**attrs)
return rc.DUPLICATE_ENTRY
except self.model.DoesNotExist:
inst = self.model(**attrs)
inst.save()
return inst
except self.model.MultipleObjectsReturned:
return rc.DUPLICATE_ENTRY
below is the error log
Piston/0.2.2 (Django 1.4) crash report:
Traceback (most recent call last):
File "C:\Python27\Lib\site-packages\django\bin\sumit\sumit\handler.py", line 27,
in create inst = self.model.objects.get(**attrs)
File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 131,
in get return self.get_query_set().get(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py", line 358,
in get clone = self.filter(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py", line 621,
in filter return self._filter_or_exclude(False, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py", line 639,
in _filter_or_exclude clone.query.add_q(Q(*args, **kwargs))
File "C:\Python27\lib\site-packages\django\db\models\sql\query.py", line 1250,
in add_q can_reuse=used_aliases, force_having=force_having)
File "C:\Python27\lib\site-packages\django\db\models\sql\query.py", line 1122,
in add_filter process_extras=process_extras)
File "C:\Python27\lib\site-packages\django\db\models\sql\query.py", line 1316,
in setup_joins "Choices are: %s" % (name, ", ".join(names)))
FieldError: **Cannot resolve keyword 'csrfmiddlewaretoken' into field.
Choices are: complete, id, name**
In short: don't do that.
Any user can send any POST parameters they want. You have no guarantee at all they won't add any random POST parameter even though your form does not contain it.
Instead of trying to filter csrfmiddlewaretoken
out of your parameters, try whitelisting those you want to include. That means, only select those that are corresponding to your model fields and you want the user to be able to filter on them.
Update:
Okay, so, how to filter it out, just to satisfy your curiosity. flatten_dict
returns a regular Python dictionary, which means you can simply del attrs['csrfmiddlewaretoken']
to remove it from the dictionary.
Update (2):
To whitelist, something like the following should work:
allowed_keys = ['complete', 'id', 'name']
attrs = dict((key, value) for key, value in ext_posted_data if key in allowed_keys)