root / userdata / rest.py @ eee0487e
History | View | Annotate | Download (5.1 kB)
1 | eee0487e | Kostas Papadimitriou | from django import http |
---|---|---|---|
2 | eee0487e | Kostas Papadimitriou | from django.template import RequestContext, loader |
3 | eee0487e | Kostas Papadimitriou | from django.utils import simplejson as json |
4 | eee0487e | Kostas Papadimitriou | from django.core import serializers |
5 | eee0487e | Kostas Papadimitriou | |
6 | eee0487e | Kostas Papadimitriou | # base view class
|
7 | eee0487e | Kostas Papadimitriou | # https://github.com/bfirsh/django-class-based-views/blob/master/class_based_views/base.py
|
8 | eee0487e | Kostas Papadimitriou | class View(object): |
9 | eee0487e | Kostas Papadimitriou | """
|
10 | eee0487e | Kostas Papadimitriou | Intentionally simple parent class for all views. Only implements
|
11 | eee0487e | Kostas Papadimitriou | dispatch-by-method and simple sanity checking.
|
12 | eee0487e | Kostas Papadimitriou | """
|
13 | eee0487e | Kostas Papadimitriou | |
14 | eee0487e | Kostas Papadimitriou | method_names = ['GET', 'POST', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE'] |
15 | eee0487e | Kostas Papadimitriou | |
16 | eee0487e | Kostas Papadimitriou | def __init__(self, *args, **kwargs): |
17 | eee0487e | Kostas Papadimitriou | """
|
18 | eee0487e | Kostas Papadimitriou | Constructor. Called in the URLconf; can contain helpful extra
|
19 | eee0487e | Kostas Papadimitriou | keyword arguments, and other things.
|
20 | eee0487e | Kostas Papadimitriou | """
|
21 | eee0487e | Kostas Papadimitriou | # Go through keyword arguments, and either save their values to our
|
22 | eee0487e | Kostas Papadimitriou | # instance, or raise an error.
|
23 | eee0487e | Kostas Papadimitriou | for key, value in kwargs.items(): |
24 | eee0487e | Kostas Papadimitriou | if key in self.method_names: |
25 | eee0487e | Kostas Papadimitriou | raise TypeError(u"You tried to pass in the %s method name as a " |
26 | eee0487e | Kostas Papadimitriou | u"keyword argument to %s(). Don't do that."
|
27 | eee0487e | Kostas Papadimitriou | % (key, self.__class__.__name__))
|
28 | eee0487e | Kostas Papadimitriou | if hasattr(self, key): |
29 | eee0487e | Kostas Papadimitriou | setattr(self, key, value) |
30 | eee0487e | Kostas Papadimitriou | else:
|
31 | eee0487e | Kostas Papadimitriou | raise TypeError(u"%s() received an invalid keyword %r" % ( |
32 | eee0487e | Kostas Papadimitriou | self.__class__.__name__,
|
33 | eee0487e | Kostas Papadimitriou | key, |
34 | eee0487e | Kostas Papadimitriou | )) |
35 | eee0487e | Kostas Papadimitriou | |
36 | eee0487e | Kostas Papadimitriou | def instance_to_dict(self, i, exclude_fields=[]): |
37 | eee0487e | Kostas Papadimitriou | """
|
38 | eee0487e | Kostas Papadimitriou | Convert model instance to python dict
|
39 | eee0487e | Kostas Papadimitriou | """
|
40 | eee0487e | Kostas Papadimitriou | d = {} |
41 | eee0487e | Kostas Papadimitriou | for field in i._meta.get_all_field_names(): |
42 | eee0487e | Kostas Papadimitriou | if field in exclude_fields: |
43 | eee0487e | Kostas Papadimitriou | continue
|
44 | eee0487e | Kostas Papadimitriou | |
45 | eee0487e | Kostas Papadimitriou | d[field] = i.__getattribute__(field) |
46 | eee0487e | Kostas Papadimitriou | return d
|
47 | eee0487e | Kostas Papadimitriou | |
48 | eee0487e | Kostas Papadimitriou | def qs_to_dict_iter(self, qs, exclude_fields=[]): |
49 | eee0487e | Kostas Papadimitriou | """
|
50 | eee0487e | Kostas Papadimitriou | Convert queryset to an iterator of model instances dicts
|
51 | eee0487e | Kostas Papadimitriou | """
|
52 | eee0487e | Kostas Papadimitriou | for i in qs: |
53 | eee0487e | Kostas Papadimitriou | yield self.instance_to_dict(i, exclude_fields) |
54 | eee0487e | Kostas Papadimitriou | |
55 | eee0487e | Kostas Papadimitriou | def json_response(self, data): |
56 | eee0487e | Kostas Papadimitriou | return http.HttpResponse(json.dumps(data))
|
57 | eee0487e | Kostas Papadimitriou | |
58 | eee0487e | Kostas Papadimitriou | @classmethod
|
59 | eee0487e | Kostas Papadimitriou | def as_view(cls, *initargs, **initkwargs): |
60 | eee0487e | Kostas Papadimitriou | """
|
61 | eee0487e | Kostas Papadimitriou | Main entry point for a request-response process.
|
62 | eee0487e | Kostas Papadimitriou | """
|
63 | eee0487e | Kostas Papadimitriou | def view(request, *args, **kwargs): |
64 | eee0487e | Kostas Papadimitriou | self = cls(*initargs, **initkwargs)
|
65 | eee0487e | Kostas Papadimitriou | return self.dispatch(request, *args, **kwargs) |
66 | eee0487e | Kostas Papadimitriou | return view
|
67 | eee0487e | Kostas Papadimitriou | |
68 | eee0487e | Kostas Papadimitriou | def dispatch(self, request, *args, **kwargs): |
69 | eee0487e | Kostas Papadimitriou | # Try to dispatch to the right method for that; if it doesn't exist,
|
70 | eee0487e | Kostas Papadimitriou | # raise a big error.
|
71 | eee0487e | Kostas Papadimitriou | if hasattr(self, request.method.upper()): |
72 | eee0487e | Kostas Papadimitriou | self.request = request
|
73 | eee0487e | Kostas Papadimitriou | self.args = args
|
74 | eee0487e | Kostas Papadimitriou | self.kwargs = kwargs
|
75 | eee0487e | Kostas Papadimitriou | data = request.raw_post_data |
76 | eee0487e | Kostas Papadimitriou | |
77 | eee0487e | Kostas Papadimitriou | if request.method.upper() in ['POST', 'PUT']: |
78 | eee0487e | Kostas Papadimitriou | # Expect json data
|
79 | eee0487e | Kostas Papadimitriou | if request.META.get('CONTENT_TYPE').startswith('application/json'): |
80 | eee0487e | Kostas Papadimitriou | try:
|
81 | eee0487e | Kostas Papadimitriou | data = json.loads(data) |
82 | eee0487e | Kostas Papadimitriou | except ValueError: |
83 | eee0487e | Kostas Papadimitriou | raise http.HttpResponseServerError('Invalid JSON data.') |
84 | eee0487e | Kostas Papadimitriou | else:
|
85 | eee0487e | Kostas Papadimitriou | raise http.HttpResponseServerError('Unsupported Content-Type.') |
86 | eee0487e | Kostas Papadimitriou | |
87 | eee0487e | Kostas Papadimitriou | return getattr(self, request.method.upper())(request, data, *args, **kwargs) |
88 | eee0487e | Kostas Papadimitriou | else:
|
89 | eee0487e | Kostas Papadimitriou | allowed_methods = [m for m in self.method_names if hasattr(self, m)] |
90 | eee0487e | Kostas Papadimitriou | return http.HttpResponseNotAllowed(allowed_methods)
|
91 | eee0487e | Kostas Papadimitriou | |
92 | eee0487e | Kostas Papadimitriou | |
93 | eee0487e | Kostas Papadimitriou | class ResourceView(View): |
94 | eee0487e | Kostas Papadimitriou | method_names = ['GET', 'POST', 'PUT', 'DELETE'] |
95 | eee0487e | Kostas Papadimitriou | |
96 | eee0487e | Kostas Papadimitriou | model = None
|
97 | eee0487e | Kostas Papadimitriou | exclude_fields = [] |
98 | eee0487e | Kostas Papadimitriou | |
99 | eee0487e | Kostas Papadimitriou | def queryset(self): |
100 | eee0487e | Kostas Papadimitriou | return self.model.objects.all() |
101 | eee0487e | Kostas Papadimitriou | |
102 | eee0487e | Kostas Papadimitriou | def instance(self): |
103 | eee0487e | Kostas Papadimitriou | """
|
104 | eee0487e | Kostas Papadimitriou | Retrieve selected instance based on url parameter
|
105 | eee0487e | Kostas Papadimitriou |
|
106 | eee0487e | Kostas Papadimitriou | id parameter should be set in urlpatterns expression
|
107 | eee0487e | Kostas Papadimitriou | """
|
108 | eee0487e | Kostas Papadimitriou | try:
|
109 | eee0487e | Kostas Papadimitriou | return self.queryset().get(pk=self.kwargs.get("id")) |
110 | eee0487e | Kostas Papadimitriou | except self.model.DoesNotExist: |
111 | eee0487e | Kostas Papadimitriou | raise http.Http404
|
112 | eee0487e | Kostas Papadimitriou | |
113 | eee0487e | Kostas Papadimitriou | def GET(self, request, data, *args, **kwargs): |
114 | eee0487e | Kostas Papadimitriou | return self.json_response(self.instance_to_dict(self.instance(), |
115 | eee0487e | Kostas Papadimitriou | self.exclude_fields))
|
116 | eee0487e | Kostas Papadimitriou | |
117 | eee0487e | Kostas Papadimitriou | def POST(self, request, data, *args, **kwargs): |
118 | eee0487e | Kostas Papadimitriou | pass
|
119 | eee0487e | Kostas Papadimitriou | |
120 | eee0487e | Kostas Papadimitriou | def DELETE(self, request, data, *args, **kwargs): |
121 | eee0487e | Kostas Papadimitriou | self.instance().delete()
|
122 | eee0487e | Kostas Papadimitriou | return HttpResponse()
|
123 | eee0487e | Kostas Papadimitriou | |
124 | eee0487e | Kostas Papadimitriou | |
125 | eee0487e | Kostas Papadimitriou | class CollectionView(View): |
126 | eee0487e | Kostas Papadimitriou | method_names = ['GET', 'POST', 'PUT', 'DELETE'] |
127 | eee0487e | Kostas Papadimitriou | |
128 | eee0487e | Kostas Papadimitriou | model = None
|
129 | eee0487e | Kostas Papadimitriou | exclude_fields = [] |
130 | eee0487e | Kostas Papadimitriou | |
131 | eee0487e | Kostas Papadimitriou | def queryset(self): |
132 | eee0487e | Kostas Papadimitriou | return self.model.objects.all() |
133 | eee0487e | Kostas Papadimitriou | |
134 | eee0487e | Kostas Papadimitriou | def GET(self, request, data, *args, **kwargs): |
135 | eee0487e | Kostas Papadimitriou | return self.json_response(list(self.qs_to_dict_iter(self.queryset(), |
136 | eee0487e | Kostas Papadimitriou | self.exclude_fields)))
|
137 | eee0487e | Kostas Papadimitriou | |
138 | eee0487e | Kostas Papadimitriou | def PUT(self, request, data, *args, **kwargs): |
139 | eee0487e | Kostas Papadimitriou | pass
|
140 | eee0487e | Kostas Papadimitriou | |
141 | eee0487e | Kostas Papadimitriou | def DELETE(self, request, data, *args, **kwargs): |
142 | eee0487e | Kostas Papadimitriou | pass
|
143 | eee0487e | Kostas Papadimitriou | |
144 | eee0487e | Kostas Papadimitriou | class UserResourceView(ResourceView): |
145 | eee0487e | Kostas Papadimitriou | """
|
146 | eee0487e | Kostas Papadimitriou | Filter resource queryset for request user entries
|
147 | eee0487e | Kostas Papadimitriou | """
|
148 | eee0487e | Kostas Papadimitriou | def queryset(self): |
149 | eee0487e | Kostas Papadimitriou | return super(UserResourceView, |
150 | eee0487e | Kostas Papadimitriou | self).queryset().filter(user=self.request.user) |
151 | eee0487e | Kostas Papadimitriou | |
152 | eee0487e | Kostas Papadimitriou | class UserCollectionView(CollectionView): |
153 | eee0487e | Kostas Papadimitriou | """
|
154 | eee0487e | Kostas Papadimitriou | Filter collection queryset for request user entries
|
155 | eee0487e | Kostas Papadimitriou | """
|
156 | eee0487e | Kostas Papadimitriou | def queryset(self): |
157 | eee0487e | Kostas Papadimitriou | return super(UserCollectionView, self).queryset().filter(user=self.request.user) |