mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-19 12:42:37 +03:00
inital work on autodiscover
This commit is contained in:
parent
b9fcea093c
commit
742e9289cf
|
@ -1,3 +1,74 @@
|
||||||
|
|
||||||
__version__ = '0.2.3'
|
__version__ = '0.2.3'
|
||||||
|
|
||||||
VERSION = __version__ # synonym
|
VERSION = __version__ # synonym
|
||||||
|
|
||||||
|
from djangorestframework.builtins import DjangoRestFrameworkSite
|
||||||
|
|
||||||
|
try:
|
||||||
|
VERSION = __import__('pkg_resources') \
|
||||||
|
.get_distribution('gargoyle').version
|
||||||
|
except Exception, e:
|
||||||
|
VERSION = 'unknown'
|
||||||
|
|
||||||
|
|
||||||
|
from django.utils.importlib import import_module
|
||||||
|
|
||||||
|
import imp
|
||||||
|
|
||||||
|
__all__ = ('autodiscover','site')
|
||||||
|
|
||||||
|
api = DjangoRestFrameworkSite()
|
||||||
|
|
||||||
|
# A flag to tell us if autodiscover is running. autodiscover will set this to
|
||||||
|
# True while running, and False when it finishes.
|
||||||
|
LOADING = False
|
||||||
|
|
||||||
|
def autodiscover():
|
||||||
|
"""
|
||||||
|
Auto-discover INSTALLED_APPS api.py modules and fail silently when
|
||||||
|
not present. This forces an import on them to register any api bits they
|
||||||
|
may want.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Bail out if autodiscover didn't finish loading from a previous call so
|
||||||
|
# that we avoid running autodiscover again when the URLconf is loaded by
|
||||||
|
# the exception handler to resolve the handler500 view. This prevents an
|
||||||
|
# admin.py module with errors from re-registering models and raising a
|
||||||
|
# spurious AlreadyRegistered exception.
|
||||||
|
global LOADING
|
||||||
|
if LOADING:
|
||||||
|
return
|
||||||
|
LOADING = True
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
for app in settings.INSTALLED_APPS:
|
||||||
|
# For each app, we need to look for a api.py inside that
|
||||||
|
# app's package. We can't use os.path here -- recall that modules may be
|
||||||
|
# imported different ways (think zip files) -- so we need to get
|
||||||
|
# the app's __path__ and look for api.py on that path.
|
||||||
|
|
||||||
|
# Step 1: find out the app's __path__ Import errors here will (and
|
||||||
|
# should) bubble up, but a missing __path__ (which is legal, but weird)
|
||||||
|
# fails silently -- apps that do weird things with __path__ might
|
||||||
|
# need to roll their own api registration.
|
||||||
|
try:
|
||||||
|
app_path = import_module(app).__path__
|
||||||
|
except (AttributeError, ImportError):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Step 2: use imp.find_module to find the app's gargoyle_conditions.py.
|
||||||
|
# For some # reason imp.find_module raises ImportError if the app can't
|
||||||
|
# be found # but doesn't actually try to import the module. So skip this
|
||||||
|
# app if its gargoyle.py doesn't exist
|
||||||
|
try:
|
||||||
|
imp.find_module('api', app_path)
|
||||||
|
except ImportError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
import_module("%s.api" % app)
|
||||||
|
print 'aaaaaaaaaaaaa',app
|
||||||
|
|
||||||
|
# autodiscover was successful, reset loading flag.
|
||||||
|
LOADING = False
|
||||||
|
|
89
djangorestframework/builtins.py
Normal file
89
djangorestframework/builtins.py
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
from djangorestframework.mixins import ListModelMixin, InstanceMixin
|
||||||
|
from django.conf.urls.defaults import patterns, url
|
||||||
|
|
||||||
|
class DjangoRestFrameworkSite(object):
|
||||||
|
app_name = 'api'
|
||||||
|
name = 'api'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self._registry = {}
|
||||||
|
super(DjangoRestFrameworkSite, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def register(self, view, resource, prefix=None, resource_name=None):
|
||||||
|
if resource_name is None:
|
||||||
|
if hasattr(resource, 'model'):
|
||||||
|
resource_name = resource.model.__name__.lower()
|
||||||
|
else:
|
||||||
|
resource_name = resource.__name__.lower()
|
||||||
|
|
||||||
|
if prefix not in self._registry:
|
||||||
|
self._registry[prefix] = {}
|
||||||
|
|
||||||
|
if resource_name not in self._registry[prefix]:
|
||||||
|
self._registry[prefix][resource_name] = []
|
||||||
|
|
||||||
|
self._registry[prefix][resource_name].append((resource, view))
|
||||||
|
|
||||||
|
|
||||||
|
# def unregister(self, prefix=None, resource_name=None, resource=None):
|
||||||
|
# """
|
||||||
|
# Unregisters a resource.
|
||||||
|
# """
|
||||||
|
# if resource_name is None and resource is not None and \
|
||||||
|
# hasattr(resource, 'model'):
|
||||||
|
# resource_name = resource.model.__name__.lower()
|
||||||
|
#
|
||||||
|
# if resource_name is None:
|
||||||
|
# # do nothing
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# prefix_registry = self._registry.get(prefix, {})
|
||||||
|
# if resource_name in prefix_registry:
|
||||||
|
# del prefix_registry[resource_name]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def urls(self):
|
||||||
|
return self.get_urls(), self.app_name, self.name
|
||||||
|
|
||||||
|
def get_urls(self):
|
||||||
|
|
||||||
|
# Site-wide views.
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add in each resource's views.
|
||||||
|
for prefix in self._registry.keys():
|
||||||
|
for resource_name in self._registry[prefix].keys():
|
||||||
|
for resource, view in self._registry[prefix][resource_name]:
|
||||||
|
urlpatterns += self.__get_urlpatterns(
|
||||||
|
prefix, resource_name, resource, view
|
||||||
|
)
|
||||||
|
|
||||||
|
return urlpatterns
|
||||||
|
|
||||||
|
def __get_urlpatterns(self, prefix, resource_name, resource, view):
|
||||||
|
"""
|
||||||
|
Calculates the URL pattern for a given resource and view
|
||||||
|
"""
|
||||||
|
if prefix is None:
|
||||||
|
prefix = ''
|
||||||
|
else:
|
||||||
|
prefix += '/'
|
||||||
|
if issubclass(view, ListModelMixin):
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
url(r'^%s%s/' % (prefix,resource_name),
|
||||||
|
view.as_view(resource=resource),
|
||||||
|
name=resource_name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif issubclass(view, InstanceMixin):
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
url(r'^%s%s/(?P<pk>[0-9]+)/$' % (prefix,resource_name),
|
||||||
|
view.as_view(resource=resource),
|
||||||
|
name=resource_name + '_change'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return urlpatterns
|
|
@ -279,13 +279,13 @@ class ModelResource(FormResource):
|
||||||
include = ('url',)
|
include = ('url',)
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, view=None, depth=None, stack=[], **kwargs):
|
def __init__(self, view):
|
||||||
"""
|
"""
|
||||||
Allow :attr:`form` and :attr:`model` attributes set on the
|
Allow :attr:`form` and :attr:`model` attributes set on the
|
||||||
:class:`View` to override the :attr:`form` and :attr:`model`
|
:class:`View` to override the :attr:`form` and :attr:`model`
|
||||||
attributes set on the :class:`Resource`.
|
attributes set on the :class:`Resource`.
|
||||||
"""
|
"""
|
||||||
super(ModelResource, self).__init__(view, depth, stack, **kwargs)
|
super(ModelResource, self).__init__(view)
|
||||||
|
|
||||||
self.model = getattr(view, 'model', None) or self.model
|
self.model = getattr(view, 'model', None) or self.model
|
||||||
|
|
||||||
|
@ -355,7 +355,7 @@ class ModelResource(FormResource):
|
||||||
# dis does teh magicks...
|
# dis does teh magicks...
|
||||||
urlconf = get_urlconf()
|
urlconf = get_urlconf()
|
||||||
resolver = get_resolver(urlconf)
|
resolver = get_resolver(urlconf)
|
||||||
|
|
||||||
possibilities = resolver.reverse_dict.getlist(self.view_callable[0])
|
possibilities = resolver.reverse_dict.getlist(self.view_callable[0])
|
||||||
for tuple_item in possibilities:
|
for tuple_item in possibilities:
|
||||||
possibility = tuple_item[0]
|
possibility = tuple_item[0]
|
||||||
|
@ -379,6 +379,14 @@ class ModelResource(FormResource):
|
||||||
return reverse(self.view_callable[0], kwargs=instance_attrs)
|
return reverse(self.view_callable[0], kwargs=instance_attrs)
|
||||||
except NoReverseMatch:
|
except NoReverseMatch:
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
model_name = instance.__class__.__name__.split('.')[0].lower()
|
||||||
|
return reverse('%s:%s_change' % ('api', model_name), args=(instance.pk,))
|
||||||
|
except NoReverseMatch:
|
||||||
|
pass
|
||||||
|
import pdb
|
||||||
|
pdb.set_trace()
|
||||||
|
|
||||||
raise _SkipField
|
raise _SkipField
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user