mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-20 13:30:59 +03:00
inital work on autodiscover
This commit is contained in:
parent
b9fcea093c
commit
742e9289cf
|
@ -1,3 +1,74 @@
|
|||
|
||||
__version__ = '0.2.3'
|
||||
|
||||
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',)
|
||||
|
||||
|
||||
def __init__(self, view=None, depth=None, stack=[], **kwargs):
|
||||
def __init__(self, view):
|
||||
"""
|
||||
Allow :attr:`form` and :attr:`model` attributes set on the
|
||||
:class:`View` to override the :attr:`form` and :attr:`model`
|
||||
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
|
||||
|
||||
|
@ -355,7 +355,7 @@ class ModelResource(FormResource):
|
|||
# dis does teh magicks...
|
||||
urlconf = get_urlconf()
|
||||
resolver = get_resolver(urlconf)
|
||||
|
||||
|
||||
possibilities = resolver.reverse_dict.getlist(self.view_callable[0])
|
||||
for tuple_item in possibilities:
|
||||
possibility = tuple_item[0]
|
||||
|
@ -379,6 +379,14 @@ class ModelResource(FormResource):
|
|||
return reverse(self.view_callable[0], kwargs=instance_attrs)
|
||||
except NoReverseMatch:
|
||||
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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user