django-admin2/djadmin2/apiviews.py
2021-10-17 17:09:23 +06:00

114 lines
3.7 KiB
Python

from django.utils.encoding import force_str
from rest_framework import fields, generics, serializers
from rest_framework.response import Response
from rest_framework.reverse import reverse as drf_reverse
from rest_framework.views import APIView
from . import utils
from .viewmixins import Admin2Mixin
API_VERSION = '0.1'
class Admin2APISerializer(serializers.HyperlinkedModelSerializer):
_default_view_name = 'admin2:%(app_label)s_%(model_name)s_api_detail'
pk = fields.ReadOnlyField()
__unicode__ = fields.ReadOnlyField(source='__str__')
def get_extra_kwargs(self):
extra_kwargs = super().get_extra_kwargs()
extra_kwargs.update({
'url': {'view_name': self._get_default_view_name(self.Meta.model)}
})
return extra_kwargs
def _get_default_view_name(self, model):
"""
Return the view name to use if 'view_name' is not specified in 'Meta'
"""
model_meta = model._meta
format_kwargs = {
'app_label': model_meta.app_label,
'model_name': model_meta.object_name.lower()
}
return self._default_view_name % format_kwargs
class Admin2APIMixin(Admin2Mixin):
model = None
raise_exception = True
def get_serializer_class(self):
if self.serializer_class is None:
model_class = self.get_model()
class ModelAPISerilizer(Admin2APISerializer):
# we need to reset this here, since we don't know anything
# about the name of the admin instance when declaring the
# Admin2APISerializer base class
_default_view_name = ':'.join((
self.model_admin.admin.name,
'%(app_label)s_%(model_name)s_api_detail'))
class Meta:
model = model_class
fields = '__all__'
return ModelAPISerilizer
return super().get_serializer_class()
class IndexAPIView(Admin2APIMixin, APIView):
apps = None
registry = None
app_verbose_names = None
app_verbose_name = None
def get_model_data(self, model):
model_admin = self.registry[model]
model_options = utils.model_options(model)
opts = {
'current_app': model_admin.admin.name,
'app_label': model_options.app_label,
'model_name': model_options.object_name.lower(),
}
model_url = drf_reverse(
'%(current_app)s:%(app_label)s_%(model_name)s_api_list' % opts,
request=self.request,
format=self.kwargs.get('format'))
model_options = utils.model_options(model)
return {
'url': model_url,
'verbose_name': force_str(model_options.verbose_name),
'verbose_name_plural': force_str(model_options.verbose_name_plural),
}
def get_app_data(self, app_label, models):
model_data = []
for model in models:
model_data.append(self.get_model_data(model))
return {
'app_label': app_label,
'models': model_data,
'app_verbose_name': force_str(self.app_verbose_names.get(app_label))
}
def get(self, request):
app_data = []
for app_label, registry in self.apps.items():
models = registry.keys()
app_data.append(self.get_app_data(app_label, models))
index_data = {
'version': API_VERSION,
'apps': app_data,
}
return Response(index_data)
class ListCreateAPIView(Admin2APIMixin, generics.ListCreateAPIView):
pass
class RetrieveUpdateDestroyAPIView(Admin2APIMixin, generics.RetrieveUpdateDestroyAPIView):
pass