├── .gitignore ├── mongoadmin ├── models.py ├── templates │ └── mongoadmin │ │ ├── base.html │ │ ├── delete_confirmation.html │ │ ├── change_list.html │ │ ├── index.html │ │ └── change_form.html ├── tests.py ├── __init__.py ├── forms.py └── views.py ├── LICENSE ├── setup.py └── README.mkd /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .DS_Store 3 | django-mongoengine.komodoproject 4 | -------------------------------------------------------------------------------- /mongoadmin/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /mongoadmin/templates/mongoadmin/base.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | {% load i18n %} 3 | 4 | {% block userlinks %} 5 | {% trans 'Log out' %} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /mongoadmin/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates two different styles of tests (one doctest and one 3 | unittest). These will both pass when you run "manage.py test". 4 | 5 | Replace these with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | class SimpleTest(TestCase): 11 | def test_basic_addition(self): 12 | """ 13 | Tests that 1 + 1 always equals 2. 14 | """ 15 | self.failUnlessEqual(1 + 1, 2) 16 | 17 | __test__ = {"doctest": """ 18 | Another way to test that 1 + 1 is equal to 2. 19 | 20 | >>> 1 + 1 == 2 21 | True 22 | """} 23 | 24 | -------------------------------------------------------------------------------- /mongoadmin/__init__.py: -------------------------------------------------------------------------------- 1 | from mongoadmin.views import MongoAdmin, site 2 | from mongoadmin.forms import MongoAdminForm 3 | 4 | def autodiscover(*args): 5 | ''' Discover submodules in Django apps that would otherwise be 6 | ignored (listeners, configforms, etc) 7 | 8 | Usage: autodiscover('configforms'[, 'listeners'[, ...]]) 9 | ''' 10 | from django.conf import settings 11 | from django.utils.importlib import import_module 12 | from django.utils.module_loading import module_has_submodule 13 | 14 | for submod in args: 15 | for app in settings.INSTALLED_APPS: 16 | mod = import_module(app) 17 | if module_has_submodule(mod, submod): 18 | import_module('%s.%s' % (app, submod)) 19 | -------------------------------------------------------------------------------- /mongoadmin/templates/mongoadmin/delete_confirmation.html: -------------------------------------------------------------------------------- 1 | {% extends "mongoadmin/base.html" %} 2 | {% load i18n %} 3 | 4 | {% block breadcrumbs %} 5 | 11 | {% endblock %} 12 | 13 | {% block content %} 14 |

{% blocktrans with object as escaped_object %}Are you sure you want to delete the {{ collection }} "{{ document }}"?{% endblocktrans %}

15 |
{{ document.to_mongo|pprint }}
16 |
{% csrf_token %} 17 |
18 | 19 | 20 |
21 |
22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) derek payton 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /mongoadmin/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.conf import settings 3 | from django.contrib.admin import widgets 4 | from mongoforms import MongoForm 5 | 6 | FORM_WIDGETS = { 7 | 'fields': { 8 | forms.DateTimeField: widgets.AdminSplitDateTime, 9 | forms.DateField: widgets.AdminDateWidget, 10 | forms.TimeField: widgets.AdminTimeWidget, 11 | forms.URLField: widgets.AdminURLFieldWidget, 12 | forms.IntegerField: widgets.AdminIntegerFieldWidget, 13 | #forms.ImageField: widgets.AdminFileWidget, ## TODO: How to handle these? 14 | #forms.FileField: widgets.AdminFileWidget, 15 | }, 16 | 'widgets': { 17 | forms.Textarea: widgets.AdminTextareaWidget, 18 | forms.TextInput: widgets.AdminTextInputWidget, 19 | } 20 | } 21 | 22 | class MongoAdminForm(MongoForm): 23 | def __init__(self, admin, *args, **kwargs): 24 | self._admin = admin 25 | super(MongoAdminForm, self).__init__(*args, **kwargs) 26 | for key, field in self.fields.items(): 27 | if field.__class__ in FORM_WIDGETS['fields']: 28 | self.fields[key].widget = FORM_WIDGETS['fields'][field.__class__]() 29 | elif field.widget.__class__ in FORM_WIDGETS['widgets']: 30 | self.fields[key].widget = FORM_WIDGETS['widgets'][field.widget.__class__]() 31 | 32 | def _media(self): 33 | form_media = forms.Media(js=(settings.ADMIN_MEDIA_PREFIX + 'js/core.js',)) 34 | form_media += super(MongoAdminForm, self).media 35 | return form_media 36 | media = property(_media) 37 | -------------------------------------------------------------------------------- /mongoadmin/templates/mongoadmin/change_list.html: -------------------------------------------------------------------------------- 1 | {% extends "mongoadmin/base.html" %} 2 | {% load adminmedia admin_list i18n %} 3 | 4 | {% block extrastyle %} 5 | {{ block.super }} 6 | 7 | {% endblock %} 8 | 9 | {% block bodyclass %}change-list{% endblock %} 10 | 11 | {% block breadcrumbs %} 12 | 16 | {% endblock %} 17 | 18 | {% block coltype %}flex{% endblock %} 19 | 20 | {% block content %} 21 |
22 | {% block object-tools %} 23 | 30 | {% endblock %} 31 |
32 | 33 | 34 | 35 | {% for header in admin.list_items %} 36 | 37 | {% endfor %} 38 | 39 | 40 | 41 | {% for document, item_list in document_list %} 42 | 43 | {% for item in item_list %} 44 | {% if forloop.first %} 45 | 46 | {% else %} 47 | 48 | {% endif %} 49 | {% endfor %} 50 | 51 | {% endfor %} 52 | 53 |
{{ header }}
{{ item }}{{ item }}
54 | {#{% block pagination %}{% pagination cl %}{% endblock %}#} 55 | 56 |
57 |
58 | {% endblock %} 59 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | from setuptools import setup, find_packages 5 | 6 | __author__ = 'Derek Payton ' 7 | __description__ = 'A basic CRUD admin interface for Django+MongoEngine, very similar to `django.contrib.admin`' 8 | __license__ = 'MIT License' 9 | __version__ = '0.1a' 10 | 11 | ## Package detection from django-registration 12 | 13 | # Compile the list of packages available, because distutils doesn't have 14 | # an easy way to do this. 15 | packages, data_files = [], [] 16 | root_dir = os.path.dirname(__file__) 17 | if root_dir: 18 | os.chdir(root_dir) 19 | 20 | for dirpath, dirnames, filenames in os.walk('mongoadmin'): 21 | # Ignore dirnames that start with '.' 22 | for i, dirname in enumerate(dirnames): 23 | if dirname.startswith('.'): del dirnames[i] 24 | if '__init__.py' in filenames: 25 | pkg = dirpath.replace(os.path.sep, '.') 26 | if os.path.altsep: 27 | pkg = pkg.replace(os.path.altsep, '.') 28 | packages.append(pkg) 29 | elif filenames: 30 | prefix = dirpath[11:] # Strip "mongoadmin/" or "mongoadmin\" 31 | for f in filenames: 32 | data_files.append(os.path.join(prefix, f)) 33 | 34 | setup( 35 | name='django-mongoadmin', 36 | version=__version__, 37 | description=__description__, 38 | long_description=__description__, 39 | classifiers=[ 40 | 'Development Status :: 3 - Alpha', 41 | 'Framework :: Django', 42 | 'Intended Audience :: Developers', 43 | 'License :: OSI Approved :: MIT License', 44 | 'Natural Language :: English', 45 | 'Operating System :: OS Independent', 46 | 'Programming Language :: Python', 47 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 48 | ], 49 | keywords='django mongoengine mongoforms mongodb', 50 | maintainer = 'Derek Payton', 51 | maintainer_email = 'derek.payton@gmail.com', 52 | url='https://github.com/dmpayton/django-mongoadmin', 53 | license=__license__, 54 | packages=packages, 55 | package_data={'mongoadmin': data_files}, 56 | package_dir={'mongoadmin': 'mongoadmin'}, 57 | zip_safe=False, 58 | ) 59 | -------------------------------------------------------------------------------- /mongoadmin/templates/mongoadmin/index.html: -------------------------------------------------------------------------------- 1 | {% extends "mongoadmin/base.html" %} 2 | {% load i18n %} 3 | 4 | {% block extrastyle %}{{ block.super }}{% endblock %} 5 | 6 | {% block coltype %}colMS{% endblock %} 7 | 8 | {% block bodyclass %}dashboard{% endblock %} 9 | 10 | {% block breadcrumbs %}{% endblock %} 11 | 12 | {% block content %} 13 |
14 | 15 | {% if doc_list %} 16 | {% regroup doc_list|dictsort:"group" by group as group_list %} 17 | {% for group in group_list %} 18 |
19 | 20 | 21 | {% for document in group.list %} 22 | 23 | 24 | 25 | 26 | 27 | {% endfor %} 28 |
{% blocktrans with group.grouper as group %}{{ group }}{% endblocktrans %}
{{ document.name|capfirst }} {% trans 'Add' %}
29 |
30 | {% endfor %} 31 | {% else %} 32 |

{% trans "You don't have permission to edit anything." %}

33 | {% endif %} 34 |
35 | {% endblock %} 36 | 37 | {% comment %} 38 | {% block sidebar %} 39 | 68 | {% endblock %} 69 | {% endcomment %} 70 | -------------------------------------------------------------------------------- /README.mkd: -------------------------------------------------------------------------------- 1 | # MongoAdmin 2 | A basic CRUD admin interface for Django+MongoEngine, very similar to `django.contrib.admin`. 3 | 4 | ----- 5 | 6 | **THIS APP HAS BEEN DEPRECATED. PLEASE SEE THE POST ON MONGOENGINE-USERS FOR MORE INFORMATION:** 7 | 8 | http://groups.google.com/group/mongoengine-users/browse_thread/thread/8c2d52ab02b3c239 9 | 10 | ----- 11 | 12 | - **Author**: Derek Payton ([http://www.dmpayton.com][0]) 13 | - **Version**: 0.1a 14 | - **License**: MIT 15 | 16 | ***Requirements:*** 17 | 18 | - [Django][1] (1.2-ish, untested with 1.1) 19 | - [MongoEngine][2] (0.4) 20 | - [django-mongoforms][3] 21 | 22 | ***Todo:*** 23 | 24 | - Changelist pagination 25 | - `mongoengine.django.auth.User` password form 26 | - Better documentation 27 | - ... Probably lots more 28 | 29 | **Caution:** 30 | 31 | I have not yet verified that this works with complicated field types, such as 32 | ListField, DictField, EmbeddedDocumentField, etc. I have a feeling these might 33 | not work, but who knows? 34 | 35 | ## Example: 36 | 37 | **urls.py** 38 | 39 | import mongoadmin 40 | from django.conf.urls.defaults import * 41 | 42 | mongoadmin.autodiscover('admin') 43 | 44 | urlpatterns += patterns('', 45 | ## ... your URLs here 46 | url(r'^mongo-admin/', include(mongoadmin.site.urls, namespace='mongoadmin')), 47 | ) 48 | 49 | 50 | **yourapp/admin.py** 51 | 52 | import mongoadmin 53 | from mongoengine.django.auth import User 54 | 55 | class UserAdmin(mongoadmin.MongoAdmin): 56 | group = 'Accounts' 57 | list_items = ('username', 'email', 'is_active', 'is_staff') 58 | 59 | def get_form(self, *args, **kwargs): 60 | form = super(UserAdmin, self).get_form(*args, **kwargs) 61 | form.fields['username'].required = True 62 | form.fields['email'].required = True 63 | return form 64 | 65 | # mongoadmin.site.register(User) # With or without the admin 66 | mongoadmin.site.register(User, UserAdmin) 67 | 68 | # Documentation 69 | 70 | ## mongoadmin.MongoAdmin 71 | 72 | **MongoAdmin.form** 73 | 74 | Similar to `ModelAdmin.form`, but a mongoform. Must inherit 75 | `mongoadmin.MongoAdminForm`. 76 | 77 | *Default: `mongoadmin.MongoAdminForm`* 78 | 79 | ---------- 80 | 81 | **MongoAdmin.group** 82 | 83 | Used to visually categorize documents on the admin index. 84 | 85 | *Default: "Documents"* 86 | 87 | ---------- 88 | 89 | **MongoAdmin.list_items** 90 | 91 | Similar to `ModelAdmin.list_display`. Each item may be an attribute or method 92 | on `mongoengine.Document` or `mongoadmin.MongoAdmin`. 93 | 94 | *Default: ['\__unicode\__']* 95 | 96 | ---------- 97 | 98 | **mongoadmin.verbose_name** 99 | 100 | Similar to `Model._meta.verbose_name`. 101 | 102 | *Default: ModelAdmin.model._class_name* 103 | 104 | ---------- 105 | 106 | **mongoadmin.verbose_name_plural** 107 | 108 | Similar to `Model._meta.verbose_name_plural`. 109 | 110 | *Default: MongoAdmin.verbose_name + 's'* 111 | 112 | ---------- 113 | 114 | [0]: http://www.dmpayton.com 115 | [1]: http://www.djangoproject.com 116 | [2]: http://www.mongoengine.org 117 | [3]: https://github.com/stephrdev/django-mongoforms 118 | -------------------------------------------------------------------------------- /mongoadmin/templates/mongoadmin/change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "mongoadmin/base.html" %} 2 | {% load i18n admin_modify adminmedia %} 3 | 4 | {% block extrahead %}{{ block.super }} 5 | {% url admin:jsi18n as jsi18nurl %} 6 | 7 | {{ form.media }} 8 | {% endblock %} 9 | 10 | {% block extrastyle %}{{ block.super }}{% endblock %} 11 | 12 | {% block coltype %}{% if ordered_objects %}colMS{% else %}colM{% endif %}{% endblock %} 13 | 14 | {# {% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %} #} 15 | 16 | {% block breadcrumbs %}{% if not is_popup %} 17 | 22 | {% endif %}{% endblock %} 23 | 24 | {% block content %} 25 |
26 | {% block object-tools %} 27 | {% if change %} 28 | 31 | {% endif %} 32 | {% endblock %} 33 |
{% csrf_token %} 34 |
35 | {% if form.errors %} 36 |

37 | {% blocktrans count form.errors|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %} 38 |

39 | {{ form.non_field_errors }} 40 | {% endif %} 41 | 42 |
43 |

{% if add %}{% trans "Add" %} {{ admin.verbose_name }}{% else %}{{ document|truncatewords:"18" }}{% endif %}

44 | {% for field in form %} 45 |
46 | {{ field.errors }} 47 |
48 | {% if field.is_checkbox %} 49 | {{ field }}{{ field.label_tag }} 50 | {% else %} 51 | {{ field.label_tag }} 52 | {% if field.is_readonly %} 53 |

{{ field.contents }}

54 | {% else %} 55 | {{ field }} 56 | {% endif %} 57 | {% endif %} 58 | {% if field.field.help_text %} 59 |

{{ field.field.help_text|safe }}

60 | {% endif %} 61 |
62 |
63 | {% endfor %} 64 |
65 | 66 |
67 | 68 | {% if change %}{% endif %} 69 | 70 | 71 |
72 | 73 |
74 |
75 |
76 | {% endblock %} 77 | -------------------------------------------------------------------------------- /mongoadmin/views.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.conf.urls.defaults import patterns, url 3 | from django.contrib.admin.views.decorators import staff_member_required 4 | from django.contrib.auth import authenticate, login 5 | from django.contrib.auth.views import logout 6 | from django.contrib import messages 7 | from django.core.urlresolvers import reverse 8 | from django.db.models.options import get_verbose_name 9 | from django.http import Http404, HttpResponse, HttpResponseRedirect 10 | from django.shortcuts import render_to_response 11 | from django.template import RequestContext 12 | from django.utils.decorators import method_decorator 13 | from django.utils.encoding import force_unicode 14 | from django.utils.functional import update_wrapper 15 | from django.utils.translation import ugettext_lazy, ugettext as _ 16 | from django.views.decorators.cache import never_cache 17 | from django.views.decorators.csrf import csrf_protect 18 | from mongoadmin.forms import MongoAdminForm 19 | from mongoengine import Document 20 | from mongoengine.django.shortcuts import get_document_or_404, get_list_or_404 21 | 22 | LOGIN_FORM_KEY = 'this_is_the_login_form' 23 | 24 | class MongoAdmin(object): 25 | group = 'Documents' 26 | list_items = [] 27 | verbose_name = None 28 | verbose_name_plural = None 29 | form = MongoAdminForm 30 | 31 | def __init__(self, model): 32 | self.model = model 33 | 34 | self.model_name = self.model._class_name 35 | 36 | ## Set defaults 37 | if not self.list_items: 38 | self.list_items.append('__unicode__') 39 | if not self.verbose_name: 40 | self.verbose_name = get_verbose_name(self.model_name) 41 | if not self.verbose_name_plural: 42 | self.verbose_name_plural = '%ss' % self.verbose_name 43 | 44 | ## Validations 45 | for attr in self.list_items: 46 | if not hasattr(self.model, attr): 47 | raise ValueError('%s is not an attribute of %s' % (attr, self.model._class_name)) 48 | 49 | if not issubclass(MongoAdminForm, self.form): 50 | raise TypeError('Form must be subclass of MongoAdminForm') 51 | 52 | def _get_items(self, document): 53 | item = [] 54 | for attr in self.list_items: 55 | if hasattr(self, attr): 56 | value = getattr(self, attr) 57 | if callable(value): 58 | value = value(document=document) 59 | elif hasattr(document, attr): 60 | value = getattr(document, attr) 61 | if callable(value): 62 | value = value() 63 | else: 64 | raise Exception(_('No attribute %(attr)s found for %(name)s') % {'attr': field, 'name': self.verbose_name}) 65 | item.append(value) 66 | return item 67 | 68 | def get_form(self, *args, **kwargs): 69 | class ThisMongoAdminForm(self.form): 70 | class Meta: 71 | document = self.model 72 | return ThisMongoAdminForm(self, *args, **kwargs) 73 | 74 | class MongoAdminSite(object): 75 | def __init__(self): 76 | self._registry = {} 77 | 78 | def register(self, cls, admin=None): 79 | admin = admin or MongoAdmin 80 | if not issubclass(cls, Document): 81 | raise TypeError('Registered documents must be a subclass of mongoengine.Document') 82 | if not issubclass(admin, MongoAdmin): 83 | raise TypeError('Document admins must be a subclass of mongoadmin.MongoAdmin') 84 | if cls in self._registry: 85 | raise ValueError('%s is already registered') 86 | self._registry[cls._meta['collection']] = (cls, admin(cls)) 87 | 88 | def unregister(self, cls): 89 | if cls in self._registry: 90 | del self._registry[cls] 91 | 92 | def verify_collection(self, collection): 93 | if collection not in self._registry: 94 | raise Http404('%s collection not found.' % collection) 95 | return self._registry[collection] 96 | 97 | def display_login_form(self, request, error_message='', extra_context=None): 98 | request.session.set_test_cookie() 99 | context = { 100 | 'title': _('Log in'), 101 | 'app_path': request.get_full_path(), 102 | 'error_message': error_message, 103 | 'root_path': 'WUT', 104 | } 105 | context.update(extra_context or {}) 106 | return render_to_response('admin/login.html', context, 107 | context_instance=RequestContext(request)) 108 | 109 | def has_permission(self, user): 110 | return user.is_active and (user.is_staff or user.is_superuser) 111 | 112 | def admin_view(self, view): 113 | @csrf_protect 114 | def inner(request, *args, **kwargs): 115 | if not self.has_permission(request.user): 116 | return self.login(request) 117 | return view(request, *args, **kwargs) 118 | return update_wrapper(inner, view) 119 | 120 | @property 121 | def urls(self): 122 | def wrap(view): 123 | def wrapper(*args, **kwargs): 124 | return self.admin_view(view)(*args, **kwargs) 125 | return update_wrapper(wrapper, view) 126 | 127 | urlpatterns = patterns('', 128 | url(r'^$', wrap(self.index_view), name='index'), 129 | url(r'^jsi18n/$', wrap(self.i18n_javascript), name='jsi18n'), 130 | url(r'^login/$', wrap(self.login), name='login'), 131 | url(r'^logout/$', wrap(self.logout), name='logout'), 132 | url(r'^(?P\w+)/$', wrap(self.changelist_view), name='changelist'), 133 | url(r'^(?P\w+)/add/$', wrap(self.change_view), name='add'), 134 | url(r'^(?P\w+)/(?P[0-9a-fA-F]+)/$', wrap(self.change_view), name='change'), 135 | url(r'^(?P\w+)/(?P[0-9a-fA-F]+)/delete/$', wrap(self.delete_view), name='delete'), 136 | ) 137 | 138 | return urlpatterns 139 | 140 | @method_decorator(never_cache) 141 | def login(self, request): 142 | # If this isn't already the login page, display it. 143 | if not request.POST.has_key(LOGIN_FORM_KEY): 144 | if request.POST: 145 | message = _('Please log in again, because your session has expired.') 146 | else: 147 | message = '' 148 | return self.display_login_form(request, message) 149 | 150 | # Check that the user accepts cookies. 151 | if not request.session.test_cookie_worked(): 152 | message = _("Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again.") 153 | return self.display_login_form(request, message) 154 | else: 155 | request.session.delete_test_cookie() 156 | 157 | # Check the password. 158 | username = request.POST.get('username') 159 | password = request.POST.get('password') 160 | user = authenticate(username=username, password=password) 161 | if not user: 162 | message = _('Sorry, the username or password you entered is invalid.') 163 | return self.display_login_form(request, message) 164 | 165 | ## Admins only 166 | if not self.has_permission(user): 167 | message = _('Only staff members and site administrators are allowed to access this page.') 168 | return self.display_login_form(request, message) 169 | 170 | ## Made it this far, we're good to go 171 | login(request, user) 172 | return HttpResponseRedirect(request.path) 173 | 174 | @method_decorator(never_cache) 175 | def logout(self, request): 176 | return logout(request) 177 | 178 | def i18n_javascript(self, request): 179 | """ 180 | Displays the i18n JavaScript that the Django admin requires. 181 | 182 | This takes into account the USE_I18N setting. If it's set to False, the 183 | generated JavaScript will be leaner and faster. 184 | """ 185 | if settings.USE_I18N: 186 | from django.views.i18n import javascript_catalog 187 | else: 188 | from django.views.i18n import null_javascript_catalog as javascript_catalog 189 | return javascript_catalog(request, packages='django.conf') 190 | 191 | @method_decorator(never_cache) 192 | def index_view(self, request): 193 | doc_list = [] 194 | for collection, (cls, admin) in self._registry.iteritems(): 195 | doc_list.append({ 196 | 'group': admin.group, 197 | 'name': admin.verbose_name, 198 | 'collection': cls._meta['collection'] 199 | }) 200 | return render_to_response('mongoadmin/index.html', { 201 | 'title': _('MongoDB Administration'), 202 | 'doc_list': doc_list 203 | }, context_instance=RequestContext(request)) 204 | 205 | @method_decorator(never_cache) 206 | def changelist_view(self, request, collection): 207 | cls, admin = self.verify_collection(collection) 208 | queryset = cls.objects.all() 209 | document_list = [(document, admin._get_items(document)) for document in queryset] 210 | return render_to_response('mongoadmin/change_list.html', { 211 | 'document_list': document_list, 212 | 'collection': collection, 213 | 'admin': admin, 214 | 'title': _('Select %s to change') % admin.verbose_name 215 | }, context_instance=RequestContext(request)) 216 | 217 | @method_decorator(never_cache) 218 | def change_view(self, request, collection, object_id=None): 219 | cls, admin = self.verify_collection(collection) 220 | if object_id: 221 | document = get_document_or_404(cls, id=object_id) 222 | form = admin.get_form(request.POST or None, instance=document) 223 | add, change = False, True 224 | else: 225 | document = None 226 | form = admin.get_form(request.POST or None) 227 | add, change = True, False 228 | 229 | if form.is_valid(): 230 | document = form.save() 231 | msg = _('The %(name)s "%(obj)s" was saved successfully.') % {'name': force_unicode(admin.verbose_name), 'obj': force_unicode(document)} 232 | if '_continue' in request.POST: 233 | redirect_url = reverse('mongoadmin:change', args=(collection, str(document.pk))) 234 | msg += ' ' + _('You may edit it again below.') 235 | elif '_addanother' in request.POST: 236 | redirect_url = reverse('mongoadmin:add', args=(collection,)) 237 | msg += ' ' + (_('You may add another %s below.') % force_unicode(admin.verbose_name)) 238 | else: 239 | redirect_url = reverse('mongoadmin:changelist', args=(collection,)) 240 | 241 | messages.info(request, msg) 242 | return HttpResponseRedirect(redirect_url) 243 | 244 | return render_to_response('mongoadmin/change_form.html', { 245 | 'document': document, 246 | 'form': form, 247 | 'collection': collection, 248 | 'admin': admin, 249 | 'add': add, 250 | 'change': change, 251 | 'title': _('Change %s') % admin.verbose_name 252 | }, context_instance=RequestContext(request)) 253 | 254 | @method_decorator(never_cache) 255 | def delete_view(self, request, collection, object_id): 256 | cls, admin = self.verify_collection(collection) 257 | document = get_document_or_404(cls, id=object_id) 258 | if request.method == 'POST': 259 | document.delete() 260 | msg = _('The %(name)s "%(obj)s" has been deleted.') % {'name': force_unicode(admin.verbose_name), 'obj': force_unicode(document)} 261 | messages.info(request, msg) 262 | return HttpResponseRedirect(reverse('mongoadmin:changelist', args=(collection,))) 263 | return render_to_response('mongoadmin/delete_confirmation.html', { 264 | 'document': document, 265 | 'collection': collection, 266 | 'admin': admin, 267 | 'title': _('Delete %s') % admin.verbose_name 268 | }, context_instance=RequestContext(request)) 269 | 270 | 271 | 272 | site = MongoAdminSite() 273 | --------------------------------------------------------------------------------