diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..d769d17 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,15 @@ +[report] +# Regexes for lines to exclude from consideration +exclude_lines = + # Don't complain about missing debug-only code: + def __repr__ + if self\.debug + + # Don't complain if tests don't hit defensive assertion code: + raise AssertionError + raise NotImplementedError + + # Don't complain if non-runnable code isn't run: + if 0: + if False: + if __name__ == .__main__.: diff --git a/.gitignore b/.gitignore index 85316c2..6911cad 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,6 @@ coverage # Sphinx docs/_build -docs/_static # Launchpad lp-cache diff --git a/.travis.yml b/.travis.yml index f7a3685..9a14417 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,3 +8,6 @@ install: - pip install -r requirements.txt script: - python runtests.py +after_script: + - pip install --quiet --use-mirrors coveralls + - coveralls diff --git a/AUTHORS.rst b/AUTHORS.rst index 4dbadf8..5433008 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -1,12 +1,19 @@ CONTRIBUTORS +============ Project Lead -=============== +------------ * Daniel Greenfeld (@pydanny / ) +Translation Managers +-------------------- + +* Henri Colas (@NotSqrt) +* Danilo Bargen (@dbrgn) + Developers -============= +---------- * Audrey Roy (@audreyr) * Peter Ingelsby (@inglesp) @@ -29,3 +36,15 @@ Developers * Ryan Balfanz (@RyanBalfanz / ) * Tom Christie (@tomchristie) * Chris Jones (@chrisjones-brack3t / ) +* Danilo Bargen (@dbrgn) +* Ignasi Fosch Alonso (@ifosch) +* Henri Colas (@NotSqrt) +* Andy Boot (@bootandy) + +Translators +----------- + +* Henri Colas (@NotSqrt) +* Danilo Bargen (@dbrgn) +* Ignasi Fosch Alonso (@ifosch) +* Margherita Zamponi (@Margherita-) diff --git a/README.rst b/README.rst index f3e3ed3..2ed7408 100644 --- a/README.rst +++ b/README.rst @@ -5,6 +5,9 @@ django-admin2 .. image:: https://travis-ci.org/pydanny/django-admin2.png :alt: Build Status :target: https://travis-ci.org/pydanny/django-admin2 +.. image:: https://coveralls.io/repos/twoscoops/django-admin2/badge.png + :alt: Coverage Status + :target: https://coveralls.io/r/twoscoops/django-admin2 One of the most useful parts of ``django.contrib.admin`` is the ability to configure various views that touch and alter data. django-admin2 is a complete rewrite of that library using modern Class-Based Views and enjoying a design focused on extendibility and adaptability. By starting over, we can avoid the legacy code and make it easier to write extensions and themes. @@ -52,6 +55,7 @@ Requirements Installation ============ + Use pip to install from PyPI: .. code-block:: python @@ -75,9 +79,9 @@ Add djadmin2 urls to your URLconf: # urls.py from django.conf.urls import patterns, include - + import djadmin2 - + djadmin2.default.autodiscover() @@ -85,9 +89,6 @@ Add djadmin2 urls to your URLconf: ... url(r'^admin2/', include(djadmin2.default.urls)), ) - - - How to write django-admin2 modules @@ -125,16 +126,16 @@ The default theme is whatever bootstrap is most current. Specifically: .. code-block:: python # settings.py - ADMIN2_THEME_DIRECTORY = "admin2/bootstrap/" + ADMIN2_THEME_DIRECTORY = "djadmin2/bootstrap/" If you create a new theme, you define it thus: .. code-block:: python # settings.py - ADMIN2_THEME_DIRECTORY = "admin2/foundation/" + ADMIN2_THEME_DIRECTORY = "djadmin2/foundation/" + - History ========= @@ -143,7 +144,7 @@ History * Implemented both Function- and Class-based Action views * Implemented ModelAdmin2.list_display - * Implemented ModelAdmin2.fieldsets + * Implemented ModelAdmin2.fieldsets * Dropdown widget now displays the selected choice * Added support for callables in ModelAdmin2.list_display * Added screenshots to README diff --git a/djadmin2/actions.py b/djadmin2/actions.py index 71ae643..a725a32 100644 --- a/djadmin2/actions.py +++ b/djadmin2/actions.py @@ -11,8 +11,10 @@ from .viewmixins import AdminModel2Mixin def get_description(action): if hasattr(action, 'description'): + # This is for classes return action.description else: + # This if for functions return capfirst(action.__name__.replace('_', ' ')) @@ -20,8 +22,11 @@ class BaseListAction(AdminModel2Mixin, TemplateView): permission_classes = (permissions.IsStaffPermission,) - empty_message = 'Items must be selected in order to perform actions on them. No items have been changed.' - success_message = 'Successfully deleted %d %s' + empty_message = ugettext_lazy( + 'Items must be selected in order to perform actions ' + 'on them. No items have been changed.' + ) + success_message = ugettext_lazy('Successfully deleted %(count)s %(items)s') queryset = None @@ -95,19 +100,21 @@ class BaseListAction(AdminModel2Mixin, TemplateView): if request.POST.get('confirmed'): if self.process_queryset() is None: - message = _(self.success_message % ( - self.item_count, self.objects_name) - ) + message = self.success_message % { + 'count': self.item_count, 'items': self.objects_name + } messages.add_message(request, messages.INFO, message) return None else: - # The user has not confirmed that they want to delete the objects, so - # render a template asking for their confirmation. + # The user has not confirmed that they want to delete the + # objects, so render a template asking for their confirmation. return self.get(request) def process_queryset(self): - raise NotImplementedError('Must be provided to do some actions with queryset') + raise NotImplementedError( + 'Must be provided to do some actions with queryset' + ) class DeleteSelectedAction(BaseListAction): diff --git a/djadmin2/core.py b/djadmin2/core.py index 46a01e9..8068509 100644 --- a/djadmin2/core.py +++ b/djadmin2/core.py @@ -124,7 +124,7 @@ class Admin2(object): url(regex=r'^$', view=self.index_view.as_view(**self.get_index_kwargs()), name='dashboard' - ), + ), url(regex='^auth/user/(?P\d+)/update/password/$', view=views.PasswordChangeView.as_view(), name='password_change' @@ -137,16 +137,14 @@ class Admin2(object): view=views.LogoutView.as_view(), name='logout' ), - url( - regex=r'^(?P\w+)/$', + url(regex=r'^(?P\w+)/$', view=self.app_index_view.as_view(**self.get_app_index_kwargs()), name='app_index' - ), - url( - regex=r'^api/v0/$', + ), + url(regex=r'^api/v0/$', view=self.api_index_view.as_view(**self.get_api_index_kwargs()), name='api_index' - ), + ), ) for model, model_admin in self.registry.iteritems(): diff --git a/djadmin2/forms.py b/djadmin2/forms.py index 719e9c2..b0cb5e9 100644 --- a/djadmin2/forms.py +++ b/djadmin2/forms.py @@ -2,9 +2,8 @@ from __future__ import unicode_literals from copy import deepcopy from django.contrib.auth import authenticate -from django.contrib.auth.forms import ( - AuthenticationForm, UserCreationForm, UserChangeForm - ) +from django.contrib.auth.forms import AuthenticationForm +from django.contrib.auth.forms import UserCreationForm, UserChangeForm import django.forms import django.forms.models import django.forms.extras.widgets @@ -225,7 +224,7 @@ def floppify_form(form_class): def modelform_factory(model, form=django.forms.models.ModelForm, fields=None, - exclude=None, formfield_callback=None, widgets=None): + exclude=None, formfield_callback=None, widgets=None): form_class = django.forms.models.modelform_factory( model=model, form=form, @@ -246,8 +245,11 @@ class AdminAuthenticationForm(AuthenticationForm): Liberally copied from django.contrib.admin.forms.AdminAuthenticationForm """ - this_is_the_login_form = django.forms.BooleanField(widget=floppyforms.HiddenInput, initial=1, - error_messages={'required': ugettext_lazy("Please log in again, because your session has expired.")}) + error_messages = { + 'required': ugettext_lazy("Please log in again, because your session has expired."), + } + this_is_the_login_form = django.forms.BooleanField(widget=floppyforms.HiddenInput, + initial=1, error_messages=error_messages) def clean(self): username = self.cleaned_data.get('username') diff --git a/djadmin2/locale/ca/LC_MESSAGES/django.po b/djadmin2/locale/ca/LC_MESSAGES/django.po new file mode 100644 index 0000000..3544e67 --- /dev/null +++ b/djadmin2/locale/ca/LC_MESSAGES/django.po @@ -0,0 +1,226 @@ +# This file is distributed under the same license as the django-admin2 package. +# +# Translators: +# Ignasi Fosch Alonso , 2013. +msgid "" +msgstr "" +"Project-Id-Version: django-admin2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-07-06 15:02+0200\n" +"PO-Revision-Date: 2013-07-06 14:47+0200\n" +"Last-Translator: Ignasi Fosch Alonso \n" +"Language-Team: https://www.transifex.com/projects/p/django-admin2/language/" +"ca/\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: actions.py:26 +msgid "" +"Items must be selected in order to perform actions on them. No items have " +"been changed." +msgstr "" + +#: actions.py:29 +#, python-format +msgid "Successfully deleted %(count)s %(items)s" +msgstr "" + +#: actions.py:127 +msgid "Delete selected items" +msgstr "" + +#: forms.py:238 +#, python-format +msgid "" +"Please enter the correct %(username)s and password for a staff account. Note " +"that both fields may be case-sensitive." +msgstr "" + +#: forms.py:249 +msgid "Please log in again, because your session has expired." +msgstr "" + +#: views.py:165 templates/admin2/bootstrap/model_update_form.html:29 +#: templates/admin2/bootstrap/includes/app_model_list.html:38 +msgid "Change" +msgstr "" + +#: views.py:179 templates/admin2/bootstrap/includes/app_model_list.html:30 +msgid "Add" +msgstr "" + +#: templates/admin2/bootstrap/app_index.html:6 +#: templates/admin2/bootstrap/base.html:55 +#: templates/admin2/bootstrap/model_confirm_delete.html:10 +#: templates/admin2/bootstrap/model_detail.html:11 +#: templates/admin2/bootstrap/model_list.html:14 +#: templates/admin2/bootstrap/model_update_form.html:11 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:10 +#: templates/admin2/bootstrap/auth/logout.html:8 +#: templates/admin2/bootstrap/auth/password_change_done.html:11 +#: templates/admin2/bootstrap/auth/password_change_form.html:10 +msgid "Home" +msgstr "" + +#: templates/admin2/bootstrap/app_index.html:12 +#, python-format +msgid "%(app_label)s administration" +msgstr "" + +#: templates/admin2/bootstrap/base.html:6 +#: templates/admin2/bootstrap/base.html:71 +#: templates/admin2/bootstrap/auth/login.html:15 +msgid "Site administration" +msgstr "" + +#: templates/admin2/bootstrap/base.html:22 +msgid "API" +msgstr "" + +#: templates/admin2/bootstrap/base.html:25 +msgid "Documentation" +msgstr "" + +#: templates/admin2/bootstrap/base.html:34 +#, python-format +msgid "Logged in as %(user)s" +msgstr "" + +#: templates/admin2/bootstrap/base.html:40 +msgid "Change password" +msgstr "" + +#: templates/admin2/bootstrap/base.html:42 +#: templates/admin2/bootstrap/auth/logout.html:11 +msgid "Log out" +msgstr "" + +#: templates/admin2/bootstrap/index.html:13 +msgid "Recent Actions" +msgstr "" + +#: templates/admin2/bootstrap/index.html:14 +msgid "My Actions" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:4 +#: templates/admin2/bootstrap/model_confirm_delete.html:6 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:4 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:6 +msgid "Are you sure?" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:25 +#: templates/admin2/bootstrap/model_update_form.html:74 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:21 +msgid "Delete" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:30 +#, python-format +msgid "" +"Are you sure you want to delete the %(model_name)s \"%(object)s\"? All of " +"the following items will be deleted:" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:40 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:40 +msgid "Yes, I'm sure" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:4 +#: templates/admin2/bootstrap/model_list.html:6 +#, python-format +msgid "Select %(model_name)s to change" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:31 +msgid "Search Term" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:32 +msgid "Search" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:59 +#, python-format +msgid "%(selected)s of %(total)s selected" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:63 +#, python-format +msgid "Add %(model_verbose_name)s" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:5 +#: templates/admin2/bootstrap/model_update_form.html:7 +#, python-format +msgid "%(action)s %(model_name)s" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:78 +msgid "Save and add another" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:79 +msgid "Save and continue editing" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:80 +msgid "Save" +msgstr "" + +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:27 +#, python-format +msgid "" +"Are you sure you want to delete the selected %(objects_name)s? All of the " +"following items will be deleted:" +msgstr "" + +#: templates/admin2/bootstrap/auth/login.html:15 +#: templates/admin2/bootstrap/auth/login.html:52 +msgid "Log in" +msgstr "" + +#: templates/admin2/bootstrap/auth/login.html:27 +#: templates/admin2/bootstrap/auth/password_change_form.html:24 +msgid "Please correct the error below." +msgid_plural "Please correct the errors below." +msgstr[0] "" +msgstr[1] "" + +#: templates/admin2/bootstrap/auth/logout.html:17 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "" + +#: templates/admin2/bootstrap/auth/logout.html:18 +msgid "Log in again" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_done.html:6 +#: templates/admin2/bootstrap/auth/password_change_done.html:7 +#: templates/admin2/bootstrap/auth/password_change_done.html:14 +msgid "Password change successful" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_done.html:20 +msgid "Your password was changed." +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:6 +#: templates/admin2/bootstrap/auth/password_change_form.html:13 +msgid "Password change" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:20 +msgid "" +"Please enter your old password, for security's sake, and then enter your new " +"password twice so we can verify you typed it in correctly." +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:31 +msgid "Change my password" +msgstr "" diff --git a/djadmin2/locale/de/LC_MESSAGES/django.po b/djadmin2/locale/de/LC_MESSAGES/django.po new file mode 100644 index 0000000..d926136 --- /dev/null +++ b/djadmin2/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,226 @@ +# This file is distributed under the same license as the django-admin2 package. +# +# Translators: +# Danilo Bargen , 2013. +msgid "" +msgstr "" +"Project-Id-Version: django-admin2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-07-06 15:02+0200\n" +"PO-Revision-Date: 2013-07-06 14:47+0200\n" +"Last-Translator: Danilo Bargen \n" +"Language-Team: https://www.transifex.com/projects/p/django-admin2/language/" +"de/\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: actions.py:26 +msgid "" +"Items must be selected in order to perform actions on them. No items have " +"been changed." +msgstr "" + +#: actions.py:29 +#, python-format +msgid "Successfully deleted %(count)s %(items)s" +msgstr "" + +#: actions.py:127 +msgid "Delete selected items" +msgstr "" + +#: forms.py:238 +#, python-format +msgid "" +"Please enter the correct %(username)s and password for a staff account. Note " +"that both fields may be case-sensitive." +msgstr "" + +#: forms.py:249 +msgid "Please log in again, because your session has expired." +msgstr "" + +#: views.py:165 templates/admin2/bootstrap/model_update_form.html:29 +#: templates/admin2/bootstrap/includes/app_model_list.html:38 +msgid "Change" +msgstr "" + +#: views.py:179 templates/admin2/bootstrap/includes/app_model_list.html:30 +msgid "Add" +msgstr "" + +#: templates/admin2/bootstrap/app_index.html:6 +#: templates/admin2/bootstrap/base.html:55 +#: templates/admin2/bootstrap/model_confirm_delete.html:10 +#: templates/admin2/bootstrap/model_detail.html:11 +#: templates/admin2/bootstrap/model_list.html:14 +#: templates/admin2/bootstrap/model_update_form.html:11 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:10 +#: templates/admin2/bootstrap/auth/logout.html:8 +#: templates/admin2/bootstrap/auth/password_change_done.html:11 +#: templates/admin2/bootstrap/auth/password_change_form.html:10 +msgid "Home" +msgstr "" + +#: templates/admin2/bootstrap/app_index.html:12 +#, python-format +msgid "%(app_label)s administration" +msgstr "" + +#: templates/admin2/bootstrap/base.html:6 +#: templates/admin2/bootstrap/base.html:71 +#: templates/admin2/bootstrap/auth/login.html:15 +msgid "Site administration" +msgstr "" + +#: templates/admin2/bootstrap/base.html:22 +msgid "API" +msgstr "" + +#: templates/admin2/bootstrap/base.html:25 +msgid "Documentation" +msgstr "" + +#: templates/admin2/bootstrap/base.html:34 +#, python-format +msgid "Logged in as %(user)s" +msgstr "" + +#: templates/admin2/bootstrap/base.html:40 +msgid "Change password" +msgstr "" + +#: templates/admin2/bootstrap/base.html:42 +#: templates/admin2/bootstrap/auth/logout.html:11 +msgid "Log out" +msgstr "" + +#: templates/admin2/bootstrap/index.html:13 +msgid "Recent Actions" +msgstr "" + +#: templates/admin2/bootstrap/index.html:14 +msgid "My Actions" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:4 +#: templates/admin2/bootstrap/model_confirm_delete.html:6 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:4 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:6 +msgid "Are you sure?" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:25 +#: templates/admin2/bootstrap/model_update_form.html:74 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:21 +msgid "Delete" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:30 +#, python-format +msgid "" +"Are you sure you want to delete the %(model_name)s \"%(object)s\"? All of " +"the following items will be deleted:" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:40 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:40 +msgid "Yes, I'm sure" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:4 +#: templates/admin2/bootstrap/model_list.html:6 +#, python-format +msgid "Select %(model_name)s to change" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:31 +msgid "Search Term" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:32 +msgid "Search" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:59 +#, python-format +msgid "%(selected)s of %(total)s selected" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:63 +#, python-format +msgid "Add %(model_verbose_name)s" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:5 +#: templates/admin2/bootstrap/model_update_form.html:7 +#, python-format +msgid "%(action)s %(model_name)s" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:78 +msgid "Save and add another" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:79 +msgid "Save and continue editing" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:80 +msgid "Save" +msgstr "" + +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:27 +#, python-format +msgid "" +"Are you sure you want to delete the selected %(objects_name)s? All of the " +"following items will be deleted:" +msgstr "" + +#: templates/admin2/bootstrap/auth/login.html:15 +#: templates/admin2/bootstrap/auth/login.html:52 +msgid "Log in" +msgstr "" + +#: templates/admin2/bootstrap/auth/login.html:27 +#: templates/admin2/bootstrap/auth/password_change_form.html:24 +msgid "Please correct the error below." +msgid_plural "Please correct the errors below." +msgstr[0] "" +msgstr[1] "" + +#: templates/admin2/bootstrap/auth/logout.html:17 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "" + +#: templates/admin2/bootstrap/auth/logout.html:18 +msgid "Log in again" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_done.html:6 +#: templates/admin2/bootstrap/auth/password_change_done.html:7 +#: templates/admin2/bootstrap/auth/password_change_done.html:14 +msgid "Password change successful" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_done.html:20 +msgid "Your password was changed." +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:6 +#: templates/admin2/bootstrap/auth/password_change_form.html:13 +msgid "Password change" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:20 +msgid "" +"Please enter your old password, for security's sake, and then enter your new " +"password twice so we can verify you typed it in correctly." +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:31 +msgid "Change my password" +msgstr "" diff --git a/djadmin2/locale/en/LC_MESSAGES/django.po b/djadmin2/locale/en/LC_MESSAGES/django.po new file mode 100644 index 0000000..1e9de12 --- /dev/null +++ b/djadmin2/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,240 @@ +# This file is distributed under the same license as the django-admin2 package. +# +# Translators: +# NotSqrt , 2013. +msgid "" +msgstr "" +"Project-Id-Version: django-admin2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-07-06 15:02+0200\n" +"PO-Revision-Date: 2013-07-06 13:27+0200\n" +"Last-Translator: NotSqrt \n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: actions.py:26 +msgid "" +"Items must be selected in order to perform actions on them. No items have " +"been changed." +msgstr "" +"Items must be selected in order to perform actions on them. No items have " +"been changed." + +#: actions.py:29 +#, python-format +msgid "Successfully deleted %(count)s %(items)s" +msgstr "Successfully deleted %(count)s %(items)s" + +#: actions.py:127 +msgid "Delete selected items" +msgstr "Delete selected items" + +#: forms.py:238 +#, python-format +msgid "" +"Please enter the correct %(username)s and password for a staff account. Note " +"that both fields may be case-sensitive." +msgstr "" +"Please enter the correct %(username)s and password for a staff account. Note " +"that both fields may be case-sensitive." + +#: forms.py:249 +msgid "Please log in again, because your session has expired." +msgstr "Please log in again, because your session has expired." + +#: views.py:165 templates/djadmin2/bootstrap/model_update_form.html:29 +#: templates/djadmin2/bootstrap/includes/app_model_list.html:38 +msgid "Change" +msgstr "Change" + +#: views.py:179 templates/djadmin2/bootstrap/includes/app_model_list.html:30 +msgid "Add" +msgstr "Add" + +#: templates/djadmin2/bootstrap/app_index.html:6 +#: templates/djadmin2/bootstrap/base.html:55 +#: templates/djadmin2/bootstrap/model_confirm_delete.html:10 +#: templates/djadmin2/bootstrap/model_detail.html:11 +#: templates/djadmin2/bootstrap/model_list.html:14 +#: templates/djadmin2/bootstrap/model_update_form.html:11 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:10 +#: templates/djadmin2/bootstrap/auth/logout.html:8 +#: templates/djadmin2/bootstrap/auth/password_change_done.html:11 +#: templates/djadmin2/bootstrap/auth/password_change_form.html:10 +msgid "Home" +msgstr "Home" + +#: templates/djadmin2/bootstrap/app_index.html:12 +#, python-format +msgid "%(app_label)s administration" +msgstr "%(app_label)s administration" + +#: templates/djadmin2/bootstrap/base.html:6 +#: templates/djadmin2/bootstrap/base.html:71 +#: templates/djadmin2/bootstrap/auth/login.html:15 +msgid "Site administration" +msgstr "Site administration" + +#: templates/djadmin2/bootstrap/base.html:22 +msgid "API" +msgstr "API" + +#: templates/djadmin2/bootstrap/base.html:25 +msgid "Documentation" +msgstr "Documentation" + +#: templates/djadmin2/bootstrap/base.html:34 +#, python-format +msgid "Logged in as %(user)s" +msgstr "Logged in as %(user)s" + +#: templates/djadmin2/bootstrap/base.html:40 +msgid "Change password" +msgstr "Change password" + +#: templates/djadmin2/bootstrap/base.html:42 +msgid "Log out" +msgstr "Log out" + +#: templates/djadmin2/bootstrap/index.html:13 +msgid "Recent Actions" +msgstr "Recent Actions" + +#: templates/djadmin2/bootstrap/index.html:14 +msgid "My Actions" +msgstr "My Actions" + +#: templates/djadmin2/bootstrap/model_confirm_delete.html:4 +#: templates/djadmin2/bootstrap/model_confirm_delete.html:6 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:4 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:6 +msgid "Are you sure?" +msgstr "Are you sure?" + +#: templates/djadmin2/bootstrap/model_confirm_delete.html:25 +#: templates/djadmin2/bootstrap/model_update_form.html:74 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:21 +msgid "Delete" +msgstr "Delete" + +#: templates/djadmin2/bootstrap/model_confirm_delete.html:30 +#, python-format +msgid "" +"Are you sure you want to delete the %(model_name)s \"%(object)s\"? All of " +"the following items will be deleted:" +msgstr "" +"Are you sure you want to delete the %(model_name)s \"%(object)s\"? All of " +"the following items will be deleted:" + +#: templates/djadmin2/bootstrap/model_confirm_delete.html:40 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:40 +msgid "Yes, I'm sure" +msgstr "Yes, I'm sure" + +#: templates/djadmin2/bootstrap/model_list.html:4 +#: templates/djadmin2/bootstrap/model_list.html:6 +#, python-format +msgid "Select %(model_name)s to change" +msgstr "Select %(model_name)s to change" + +#: templates/djadmin2/bootstrap/model_list.html:31 +msgid "Search Term" +msgstr "Search Term" + +#: templates/djadmin2/bootstrap/model_list.html:32 +msgid "Search" +msgstr "Search" + +#: templates/djadmin2/bootstrap/model_list.html:59 +#, python-format +msgid "%(selected)s of %(total)s selected" +msgstr "%(selected)s of %(total)s selected" + +#: templates/djadmin2/bootstrap/model_list.html:63 +#, python-format +msgid "Add %(model_verbose_name)s" +msgstr "Add %(model_verbose_name)s" + +#: templates/djadmin2/bootstrap/model_update_form.html:5 +#: templates/djadmin2/bootstrap/model_update_form.html:7 +#, python-format +msgid "%(action)s %(model_name)s" +msgstr "%(action)s %(model_name)s" + +#: templates/djadmin2/bootstrap/model_update_form.html:78 +msgid "Save and add another" +msgstr "Save and add another" + +#: templates/djadmin2/bootstrap/model_update_form.html:79 +msgid "Save and continue editing" +msgstr "Save and continue editing" + +#: templates/djadmin2/bootstrap/model_update_form.html:80 +msgid "Save" +msgstr "Save" + +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:27 +#, python-format +msgid "" +"Are you sure you want to delete the selected %(objects_name)s? All of the " +"following items will be deleted:" +msgstr "" +"Are you sure you want to delete the selected %(objects_name)s? All of the " +"following items will be deleted:" + +#: templates/djadmin2/bootstrap/auth/login.html:15 +msgid "Login" +msgstr "Login" + +#: templates/djadmin2/bootstrap/auth/login.html:27 +#: templates/djadmin2/bootstrap/auth/password_change_form.html:24 +msgid "Please correct the error below." +msgid_plural "Please correct the errors below." +msgstr[0] "Please correct the error below." +msgstr[1] "Please correct the errors below." + +#: templates/djadmin2/bootstrap/auth/login.html:52 +msgid "Log in" +msgstr "Log in" + +#: templates/djadmin2/bootstrap/auth/logout.html:11 +msgid "Logout" +msgstr "Logout" + +#: templates/djadmin2/bootstrap/auth/logout.html:17 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "Thanks for spending some quality time with the Web site today." + +#: templates/djadmin2/bootstrap/auth/logout.html:18 +msgid "Log in again" +msgstr "Log in again" + +#: templates/djadmin2/bootstrap/auth/password_change_done.html:6 +#: templates/djadmin2/bootstrap/auth/password_change_done.html:7 +#: templates/djadmin2/bootstrap/auth/password_change_done.html:14 +msgid "Password change successful" +msgstr "Password change successful" + +#: templates/djadmin2/bootstrap/auth/password_change_done.html:20 +msgid "Your password was changed." +msgstr "Your password was changed." + +#: templates/djadmin2/bootstrap/auth/password_change_form.html:6 +#: templates/djadmin2/bootstrap/auth/password_change_form.html:13 +msgid "Password change" +msgstr "Password change" + +#: templates/djadmin2/bootstrap/auth/password_change_form.html:20 +msgid "" +"Please enter your old password, for security's sake, and then enter your new " +"password twice so we can verify you typed it in correctly." +msgstr "" +"Please enter your old password, for security's sake, and then enter your new " +"password twice so we can verify you typed it in correctly." + +#: templates/djadmin2/bootstrap/auth/password_change_form.html:31 +msgid "Change my password" +msgstr "Change my password" diff --git a/djadmin2/locale/es/LC_MESSAGES/django.po b/djadmin2/locale/es/LC_MESSAGES/django.po new file mode 100644 index 0000000..b75ade1 --- /dev/null +++ b/djadmin2/locale/es/LC_MESSAGES/django.po @@ -0,0 +1,226 @@ +# This file is distributed under the same license as the django-admin2 package. +# +# Translators: +# Danilo Bargen , 2013. +msgid "" +msgstr "" +"Project-Id-Version: django-admin2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-07-06 15:02+0200\n" +"PO-Revision-Date: 2013-07-06 14:47+0200\n" +"Last-Translator: Danilo Bargen \n" +"Language-Team: https://www.transifex.com/projects/p/django-admin2/language/" +"es/\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: actions.py:26 +msgid "" +"Items must be selected in order to perform actions on them. No items have " +"been changed." +msgstr "" + +#: actions.py:29 +#, python-format +msgid "Successfully deleted %(count)s %(items)s" +msgstr "" + +#: actions.py:127 +msgid "Delete selected items" +msgstr "" + +#: forms.py:238 +#, python-format +msgid "" +"Please enter the correct %(username)s and password for a staff account. Note " +"that both fields may be case-sensitive." +msgstr "" + +#: forms.py:249 +msgid "Please log in again, because your session has expired." +msgstr "" + +#: views.py:165 templates/admin2/bootstrap/model_update_form.html:29 +#: templates/admin2/bootstrap/includes/app_model_list.html:38 +msgid "Change" +msgstr "" + +#: views.py:179 templates/admin2/bootstrap/includes/app_model_list.html:30 +msgid "Add" +msgstr "" + +#: templates/admin2/bootstrap/app_index.html:6 +#: templates/admin2/bootstrap/base.html:55 +#: templates/admin2/bootstrap/model_confirm_delete.html:10 +#: templates/admin2/bootstrap/model_detail.html:11 +#: templates/admin2/bootstrap/model_list.html:14 +#: templates/admin2/bootstrap/model_update_form.html:11 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:10 +#: templates/admin2/bootstrap/auth/logout.html:8 +#: templates/admin2/bootstrap/auth/password_change_done.html:11 +#: templates/admin2/bootstrap/auth/password_change_form.html:10 +msgid "Home" +msgstr "" + +#: templates/admin2/bootstrap/app_index.html:12 +#, python-format +msgid "%(app_label)s administration" +msgstr "" + +#: templates/admin2/bootstrap/base.html:6 +#: templates/admin2/bootstrap/base.html:71 +#: templates/admin2/bootstrap/auth/login.html:15 +msgid "Site administration" +msgstr "" + +#: templates/admin2/bootstrap/base.html:22 +msgid "API" +msgstr "" + +#: templates/admin2/bootstrap/base.html:25 +msgid "Documentation" +msgstr "" + +#: templates/admin2/bootstrap/base.html:34 +#, python-format +msgid "Logged in as %(user)s" +msgstr "" + +#: templates/admin2/bootstrap/base.html:40 +msgid "Change password" +msgstr "" + +#: templates/admin2/bootstrap/base.html:42 +#: templates/admin2/bootstrap/auth/logout.html:11 +msgid "Log out" +msgstr "" + +#: templates/admin2/bootstrap/index.html:13 +msgid "Recent Actions" +msgstr "" + +#: templates/admin2/bootstrap/index.html:14 +msgid "My Actions" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:4 +#: templates/admin2/bootstrap/model_confirm_delete.html:6 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:4 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:6 +msgid "Are you sure?" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:25 +#: templates/admin2/bootstrap/model_update_form.html:74 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:21 +msgid "Delete" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:30 +#, python-format +msgid "" +"Are you sure you want to delete the %(model_name)s \"%(object)s\"? All of " +"the following items will be deleted:" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:40 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:40 +msgid "Yes, I'm sure" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:4 +#: templates/admin2/bootstrap/model_list.html:6 +#, python-format +msgid "Select %(model_name)s to change" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:31 +msgid "Search Term" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:32 +msgid "Search" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:59 +#, python-format +msgid "%(selected)s of %(total)s selected" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:63 +#, python-format +msgid "Add %(model_verbose_name)s" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:5 +#: templates/admin2/bootstrap/model_update_form.html:7 +#, python-format +msgid "%(action)s %(model_name)s" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:78 +msgid "Save and add another" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:79 +msgid "Save and continue editing" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:80 +msgid "Save" +msgstr "" + +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:27 +#, python-format +msgid "" +"Are you sure you want to delete the selected %(objects_name)s? All of the " +"following items will be deleted:" +msgstr "" + +#: templates/admin2/bootstrap/auth/login.html:15 +#: templates/admin2/bootstrap/auth/login.html:52 +msgid "Log in" +msgstr "" + +#: templates/admin2/bootstrap/auth/login.html:27 +#: templates/admin2/bootstrap/auth/password_change_form.html:24 +msgid "Please correct the error below." +msgid_plural "Please correct the errors below." +msgstr[0] "" +msgstr[1] "" + +#: templates/admin2/bootstrap/auth/logout.html:17 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "" + +#: templates/admin2/bootstrap/auth/logout.html:18 +msgid "Log in again" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_done.html:6 +#: templates/admin2/bootstrap/auth/password_change_done.html:7 +#: templates/admin2/bootstrap/auth/password_change_done.html:14 +msgid "Password change successful" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_done.html:20 +msgid "Your password was changed." +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:6 +#: templates/admin2/bootstrap/auth/password_change_form.html:13 +msgid "Password change" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:20 +msgid "" +"Please enter your old password, for security's sake, and then enter your new " +"password twice so we can verify you typed it in correctly." +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:31 +msgid "Change my password" +msgstr "" diff --git a/djadmin2/locale/fr/LC_MESSAGES/django.po b/djadmin2/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 0000000..3a70987 --- /dev/null +++ b/djadmin2/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,244 @@ +# This file is distributed under the same license as the django-admin2 package. +# +# Translators: +# NotSqrt , 2013. +msgid "" +msgstr "" +"Project-Id-Version: django-admin2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-07-06 15:02+0200\n" +"PO-Revision-Date: 2013-07-06 13:27+0200\n" +"Last-Translator: NotSqrt \n" +"Language-Team: https://www.transifex.com/projects/p/django-admin2/language/" +"fr/\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n>1;\n" + +#: actions.py:26 +msgid "" +"Items must be selected in order to perform actions on them. No items have " +"been changed." +msgstr "" +"Des éléments doivent être sélectionnés afin d'appliquer les actions. Aucun " +"élément n'a été modifié." + +#: actions.py:29 +#, python-format +msgid "Successfully deleted %(count)s %(items)s" +msgstr "La suppression de %(count)s %(items)s a réussi." + +#: actions.py:127 +msgid "Delete selected items" +msgstr "Supprimer les objets sélectionnés" + +#: forms.py:238 +#, python-format +msgid "" +"Please enter the correct %(username)s and password for a staff account. Note " +"that both fields may be case-sensitive." +msgstr "" +"Veuillez compléter correctement les champs « %(username)s » et « mot de " +"passe » d'un compte autorisé. Sachez que les deux champs peuvent être " +"sensibles à la casse." + +#: forms.py:249 +msgid "Please log in again, because your session has expired." +msgstr "Reconnectez-vous car votre session a expiré." + +#: views.py:165 templates/djadmin2/bootstrap/model_update_form.html:29 +#: templates/djadmin2/bootstrap/includes/app_model_list.html:38 +msgid "Change" +msgstr "Modifier" + +#: views.py:179 templates/djadmin2/bootstrap/includes/app_model_list.html:30 +msgid "Add" +msgstr "Ajouter" + +#: templates/djadmin2/bootstrap/app_index.html:6 +#: templates/djadmin2/bootstrap/base.html:55 +#: templates/djadmin2/bootstrap/model_confirm_delete.html:10 +#: templates/djadmin2/bootstrap/model_detail.html:11 +#: templates/djadmin2/bootstrap/model_list.html:14 +#: templates/djadmin2/bootstrap/model_update_form.html:11 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:10 +#: templates/djadmin2/bootstrap/auth/logout.html:8 +#: templates/djadmin2/bootstrap/auth/password_change_done.html:11 +#: templates/djadmin2/bootstrap/auth/password_change_form.html:10 +msgid "Home" +msgstr "Accueil" + +#: templates/djadmin2/bootstrap/app_index.html:12 +#, python-format +msgid "%(app_label)s administration" +msgstr "Administration de %(app_label)s" + +#: templates/djadmin2/bootstrap/base.html:6 +#: templates/djadmin2/bootstrap/base.html:71 +#: templates/djadmin2/bootstrap/auth/login.html:15 +msgid "Site administration" +msgstr "Administration du site" + +#: templates/djadmin2/bootstrap/base.html:22 +msgid "API" +msgstr "API" + +#: templates/djadmin2/bootstrap/base.html:25 +msgid "Documentation" +msgstr "Documentation" + +#: templates/djadmin2/bootstrap/base.html:34 +#, python-format +msgid "Logged in as %(user)s" +msgstr "Connecté en tant que %(user)s" + +#: templates/djadmin2/bootstrap/base.html:40 +msgid "Change password" +msgstr "Modifier votre mot de passe" + +#: templates/djadmin2/bootstrap/base.html:42 +msgid "Log out" +msgstr "Déconnexion" + +#: templates/djadmin2/bootstrap/index.html:13 +msgid "Recent Actions" +msgstr "Actions récentes" + +#: templates/djadmin2/bootstrap/index.html:14 +msgid "My Actions" +msgstr "Mes actions" + +#: templates/djadmin2/bootstrap/model_confirm_delete.html:4 +#: templates/djadmin2/bootstrap/model_confirm_delete.html:6 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:4 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:6 +msgid "Are you sure?" +msgstr "Êtes-vous sûr ?" + +#: templates/djadmin2/bootstrap/model_confirm_delete.html:25 +#: templates/djadmin2/bootstrap/model_update_form.html:74 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:21 +msgid "Delete" +msgstr "Supprimer" + +#: templates/djadmin2/bootstrap/model_confirm_delete.html:30 +#, python-format +msgid "" +"Are you sure you want to delete the %(model_name)s \"%(object)s\"? All of " +"the following items will be deleted:" +msgstr "" +"Voulez-vous vraiment supprimer l'objet %(model_name)s « %(object)s » ? Les " +"éléments suivants seront supprimés :" + +#: templates/djadmin2/bootstrap/model_confirm_delete.html:40 +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:40 +msgid "Yes, I'm sure" +msgstr "Oui, je suis sûr" + +#: templates/djadmin2/bootstrap/model_list.html:4 +#: templates/djadmin2/bootstrap/model_list.html:6 +#, python-format +msgid "Select %(model_name)s to change" +msgstr "Sélectionnez l'objet %(model_name)s à modifier" + +#: templates/djadmin2/bootstrap/model_list.html:31 +msgid "Search Term" +msgstr "Terme à rechercher" + +#: templates/djadmin2/bootstrap/model_list.html:32 +msgid "Search" +msgstr "Recherche" + +#: templates/djadmin2/bootstrap/model_list.html:59 +#, python-format +msgid "%(selected)s of %(total)s selected" +msgstr "%(selected)s sur %(total)s sélectionnés" + +#: templates/djadmin2/bootstrap/model_list.html:63 +#, python-format +msgid "Add %(model_verbose_name)s" +msgstr "Ajouter %(model_verbose_name)s" + +#: templates/djadmin2/bootstrap/model_update_form.html:5 +#: templates/djadmin2/bootstrap/model_update_form.html:7 +#, python-format +msgid "%(action)s %(model_name)s" +msgstr "%(action)s %(model_name)s" + +#: templates/djadmin2/bootstrap/model_update_form.html:78 +msgid "Save and add another" +msgstr "Enregistrer et ajouter un nouveau" + +#: templates/djadmin2/bootstrap/model_update_form.html:79 +msgid "Save and continue editing" +msgstr "Enregistrer et continuer les modifications" + +#: templates/djadmin2/bootstrap/model_update_form.html:80 +msgid "Save" +msgstr "Enregistrer" + +#: templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html:27 +#, python-format +msgid "" +"Are you sure you want to delete the selected %(objects_name)s? All of the " +"following items will be deleted:" +msgstr "" +"Voulez-vous vraiment supprimer les objets %(objects_name)s sélectionnés ? " +"Les éléments suivants seront supprimés :" + +#: templates/djadmin2/bootstrap/auth/login.html:15 +msgid "Login" +msgstr "Connexion" + +#: templates/djadmin2/bootstrap/auth/login.html:27 +#: templates/djadmin2/bootstrap/auth/password_change_form.html:24 +msgid "Please correct the error below." +msgid_plural "Please correct the errors below." +msgstr[0] "Corrigez l'erreur suivante." +msgstr[1] "Corrigez les erreurs suivantes." + +#: templates/djadmin2/bootstrap/auth/login.html:52 +msgid "Log in" +msgstr "Connexion" + +#: templates/djadmin2/bootstrap/auth/logout.html:11 +msgid "Logout" +msgstr "Déconnexion" + +#: templates/djadmin2/bootstrap/auth/logout.html:17 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "Merci pour le temps que vous avez accordé à ce site aujourd'hui." + +#: templates/djadmin2/bootstrap/auth/logout.html:18 +msgid "Log in again" +msgstr "Connectez-vous à nouveau" + +#: templates/djadmin2/bootstrap/auth/password_change_done.html:6 +#: templates/djadmin2/bootstrap/auth/password_change_done.html:7 +#: templates/djadmin2/bootstrap/auth/password_change_done.html:14 +msgid "Password change successful" +msgstr "Mot de passe modifié avec succès" + +#: templates/djadmin2/bootstrap/auth/password_change_done.html:20 +msgid "Your password was changed." +msgstr "Votre mot de passe a été modifié." + +#: templates/djadmin2/bootstrap/auth/password_change_form.html:6 +#: templates/djadmin2/bootstrap/auth/password_change_form.html:13 +msgid "Password change" +msgstr "Modification de votre mot de passe" + +#: templates/djadmin2/bootstrap/auth/password_change_form.html:20 +msgid "" +"Please enter your old password, for security's sake, and then enter your new " +"password twice so we can verify you typed it in correctly." +msgstr "" +"Pour des raisons de sécurité, saisissez votre ancien mot de passe puis votre " +"nouveau mot de passe à deux reprises afin de vérifier qu'il est correctement " +"saisi." + +#: templates/djadmin2/bootstrap/auth/password_change_form.html:31 +msgid "Change my password" +msgstr "Modifier mon mot de passe" diff --git a/djadmin2/locale/it/LC_MESSAGES/django.po b/djadmin2/locale/it/LC_MESSAGES/django.po new file mode 100644 index 0000000..a29e56b --- /dev/null +++ b/djadmin2/locale/it/LC_MESSAGES/django.po @@ -0,0 +1,226 @@ +# This file is distributed under the same license as the django-admin2 package. +# +# Translators: +# Margherita Zamponi +msgid "" +msgstr "" +"Project-Id-Version: django-admin2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-07-06 15:02+0200\n" +"PO-Revision-Date: 2013-07-06 14:47+0200\n" +"Last-Translator: Margherita Zamponi \n" +"Language-Team: https://www.transifex.com/projects/p/django-admin2/language/" +"it/\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: actions.py:26 +msgid "" +"Items must be selected in order to perform actions on them. No items have " +"been changed." +msgstr "" + +#: actions.py:29 +#, python-format +msgid "Successfully deleted %(count)s %(items)s" +msgstr "" + +#: actions.py:127 +msgid "Delete selected items" +msgstr "" + +#: forms.py:238 +#, python-format +msgid "" +"Please enter the correct %(username)s and password for a staff account. Note " +"that both fields may be case-sensitive." +msgstr "" + +#: forms.py:249 +msgid "Please log in again, because your session has expired." +msgstr "" + +#: views.py:165 templates/admin2/bootstrap/model_update_form.html:29 +#: templates/admin2/bootstrap/includes/app_model_list.html:38 +msgid "Change" +msgstr "" + +#: views.py:179 templates/admin2/bootstrap/includes/app_model_list.html:30 +msgid "Add" +msgstr "" + +#: templates/admin2/bootstrap/app_index.html:6 +#: templates/admin2/bootstrap/base.html:55 +#: templates/admin2/bootstrap/model_confirm_delete.html:10 +#: templates/admin2/bootstrap/model_detail.html:11 +#: templates/admin2/bootstrap/model_list.html:14 +#: templates/admin2/bootstrap/model_update_form.html:11 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:10 +#: templates/admin2/bootstrap/auth/logout.html:8 +#: templates/admin2/bootstrap/auth/password_change_done.html:11 +#: templates/admin2/bootstrap/auth/password_change_form.html:10 +msgid "Home" +msgstr "" + +#: templates/admin2/bootstrap/app_index.html:12 +#, python-format +msgid "%(app_label)s administration" +msgstr "" + +#: templates/admin2/bootstrap/base.html:6 +#: templates/admin2/bootstrap/base.html:71 +#: templates/admin2/bootstrap/auth/login.html:15 +msgid "Site administration" +msgstr "" + +#: templates/admin2/bootstrap/base.html:22 +msgid "API" +msgstr "" + +#: templates/admin2/bootstrap/base.html:25 +msgid "Documentation" +msgstr "" + +#: templates/admin2/bootstrap/base.html:34 +#, python-format +msgid "Logged in as %(user)s" +msgstr "" + +#: templates/admin2/bootstrap/base.html:40 +msgid "Change password" +msgstr "" + +#: templates/admin2/bootstrap/base.html:42 +#: templates/admin2/bootstrap/auth/logout.html:11 +msgid "Log out" +msgstr "" + +#: templates/admin2/bootstrap/index.html:13 +msgid "Recent Actions" +msgstr "" + +#: templates/admin2/bootstrap/index.html:14 +msgid "My Actions" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:4 +#: templates/admin2/bootstrap/model_confirm_delete.html:6 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:4 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:6 +msgid "Are you sure?" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:25 +#: templates/admin2/bootstrap/model_update_form.html:74 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:21 +msgid "Delete" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:30 +#, python-format +msgid "" +"Are you sure you want to delete the %(model_name)s \"%(object)s\"? All of " +"the following items will be deleted:" +msgstr "" + +#: templates/admin2/bootstrap/model_confirm_delete.html:40 +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:40 +msgid "Yes, I'm sure" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:4 +#: templates/admin2/bootstrap/model_list.html:6 +#, python-format +msgid "Select %(model_name)s to change" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:31 +msgid "Search Term" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:32 +msgid "Search" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:59 +#, python-format +msgid "%(selected)s of %(total)s selected" +msgstr "" + +#: templates/admin2/bootstrap/model_list.html:63 +#, python-format +msgid "Add %(model_verbose_name)s" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:5 +#: templates/admin2/bootstrap/model_update_form.html:7 +#, python-format +msgid "%(action)s %(model_name)s" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:78 +msgid "Save and add another" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:79 +msgid "Save and continue editing" +msgstr "" + +#: templates/admin2/bootstrap/model_update_form.html:80 +msgid "Save" +msgstr "" + +#: templates/admin2/bootstrap/actions/delete_selected_confirmation.html:27 +#, python-format +msgid "" +"Are you sure you want to delete the selected %(objects_name)s? All of the " +"following items will be deleted:" +msgstr "" + +#: templates/admin2/bootstrap/auth/login.html:15 +#: templates/admin2/bootstrap/auth/login.html:52 +msgid "Log in" +msgstr "" + +#: templates/admin2/bootstrap/auth/login.html:27 +#: templates/admin2/bootstrap/auth/password_change_form.html:24 +msgid "Please correct the error below." +msgid_plural "Please correct the errors below." +msgstr[0] "" +msgstr[1] "" + +#: templates/admin2/bootstrap/auth/logout.html:17 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "" + +#: templates/admin2/bootstrap/auth/logout.html:18 +msgid "Log in again" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_done.html:6 +#: templates/admin2/bootstrap/auth/password_change_done.html:7 +#: templates/admin2/bootstrap/auth/password_change_done.html:14 +msgid "Password change successful" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_done.html:20 +msgid "Your password was changed." +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:6 +#: templates/admin2/bootstrap/auth/password_change_form.html:13 +msgid "Password change" +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:20 +msgid "" +"Please enter your old password, for security's sake, and then enter your new " +"password twice so we can verify you typed it in correctly." +msgstr "" + +#: templates/admin2/bootstrap/auth/password_change_form.html:31 +msgid "Change my password" +msgstr "" diff --git a/djadmin2/settings.py b/djadmin2/settings.py index b84b862..ec3d674 100644 --- a/djadmin2/settings.py +++ b/djadmin2/settings.py @@ -6,4 +6,4 @@ MODEL_ADMIN_ATTRS = ( 'index_view', 'detail_view', 'create_view', 'update_view', 'delete_view', 'get_default_view_kwargs', 'get_list_actions') -ADMIN2_THEME_DIRECTORY = getattr(settings, "ADMIN2_THEME_DIRECTORY", "admin2/bootstrap") +ADMIN2_THEME_DIRECTORY = getattr(settings, "ADMIN2_THEME_DIRECTORY", "djadmin2/bootstrap") diff --git a/djadmin2/templates/admin2/bootstrap/actions/delete_selected_confirmation.html b/djadmin2/templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html similarity index 81% rename from djadmin2/templates/admin2/bootstrap/actions/delete_selected_confirmation.html rename to djadmin2/templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html index e4d0911..1639cfd 100644 --- a/djadmin2/templates/admin2/bootstrap/actions/delete_selected_confirmation.html +++ b/djadmin2/templates/djadmin2/bootstrap/actions/delete_selected_confirmation.html @@ -1,13 +1,13 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load admin2_tags i18n %} -{% block title %}Are you sure?{% endblock title %} +{% block title %}{% trans "Are you sure?" %}{% endblock title %} -{% block page_title %}Are you sure?{% endblock page_title %} +{% block page_title %}{% trans "Are you sure?" %}{% endblock page_title %} {% block breadcrumbs %}
  • - Home + {% trans "Home" %} /
  • diff --git a/djadmin2/templates/admin2/bootstrap/app_index.html b/djadmin2/templates/djadmin2/bootstrap/app_index.html similarity index 70% rename from djadmin2/templates/admin2/bootstrap/app_index.html rename to djadmin2/templates/djadmin2/bootstrap/app_index.html index fc2be4d..26b50a9 100644 --- a/djadmin2/templates/admin2/bootstrap/app_index.html +++ b/djadmin2/templates/djadmin2/bootstrap/app_index.html @@ -1,9 +1,9 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load admin2_tags i18n %} {% block breadcrumbs %}
  • - Home + {% trans "Home" %} /
  • {{ app_label|title }}
  • @@ -14,7 +14,7 @@ {% block content %}
    - {% include 'admin2/bootstrap/includes/app_model_list.html' %} + {% include 'djadmin2/bootstrap/includes/app_model_list.html' %}
    {% endblock content %} diff --git a/djadmin2/templates/admin2/bootstrap/auth/login.html b/djadmin2/templates/djadmin2/bootstrap/auth/login.html similarity index 94% rename from djadmin2/templates/admin2/bootstrap/auth/login.html rename to djadmin2/templates/djadmin2/bootstrap/auth/login.html index 128a9c1..0c90a6f 100644 --- a/djadmin2/templates/admin2/bootstrap/auth/login.html +++ b/djadmin2/templates/djadmin2/bootstrap/auth/login.html @@ -1,4 +1,4 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load i18n %} {% load admin2_tags %} @@ -12,7 +12,7 @@ {% block breacrumbs %}{% endblock breacrumbs %} {% block class_page_title %}span12 login-title{% endblock class_page_title %} -{% block page_title %}{% trans "Site administration" %} - Login{% endblock page_title %} +{% block page_title %}{% trans "Site administration" %} - {% trans "Log in" %}{% endblock page_title %} {% block content %}
    diff --git a/djadmin2/templates/admin2/bootstrap/auth/logout.html b/djadmin2/templates/djadmin2/bootstrap/auth/logout.html similarity index 72% rename from djadmin2/templates/admin2/bootstrap/auth/logout.html rename to djadmin2/templates/djadmin2/bootstrap/auth/logout.html index 25f383f..f8c05c7 100644 --- a/djadmin2/templates/admin2/bootstrap/auth/logout.html +++ b/djadmin2/templates/djadmin2/bootstrap/auth/logout.html @@ -1,14 +1,14 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load i18n %} {% load admin2_tags %} {% block breadcrumbs %}
  • - Home + {% trans "Home" %} /
  • -
  • {% trans "Logout" %}
  • +
  • {% trans "Log out" %}
  • {% endblock breadcrumbs %} {% block content %} diff --git a/djadmin2/templates/admin2/bootstrap/auth/password_change_done.html b/djadmin2/templates/djadmin2/bootstrap/auth/password_change_done.html similarity index 82% rename from djadmin2/templates/admin2/bootstrap/auth/password_change_done.html rename to djadmin2/templates/djadmin2/bootstrap/auth/password_change_done.html index 66a45ee..85ecc89 100644 --- a/djadmin2/templates/admin2/bootstrap/auth/password_change_done.html +++ b/djadmin2/templates/djadmin2/bootstrap/auth/password_change_done.html @@ -1,4 +1,4 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load i18n %} {% load admin2_tags %} @@ -8,7 +8,7 @@ {% block breadcrumbs %}
  • - Home + {% trans "Home" %} /
  • {% trans "Password change successful" %}
  • diff --git a/djadmin2/templates/admin2/bootstrap/auth/password_change_form.html b/djadmin2/templates/djadmin2/bootstrap/auth/password_change_form.html similarity index 76% rename from djadmin2/templates/admin2/bootstrap/auth/password_change_form.html rename to djadmin2/templates/djadmin2/bootstrap/auth/password_change_form.html index f49abe7..ae06ac0 100644 --- a/djadmin2/templates/admin2/bootstrap/auth/password_change_form.html +++ b/djadmin2/templates/djadmin2/bootstrap/auth/password_change_form.html @@ -1,4 +1,4 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load i18n %} {% load admin2_tags %} @@ -7,7 +7,7 @@ {% block breadcrumbs %}
  • - Home + {% trans "Home" %} /
  • {% trans "Password change" %} /
  • @@ -17,7 +17,7 @@ {% block content %}
    -

    Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly.

    +

    {% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}

    {% if form.errors %}

    diff --git a/djadmin2/templates/admin2/bootstrap/base.html b/djadmin2/templates/djadmin2/bootstrap/base.html similarity index 91% rename from djadmin2/templates/admin2/bootstrap/base.html rename to djadmin2/templates/djadmin2/bootstrap/base.html index dd2448f..f65acf4 100644 --- a/djadmin2/templates/admin2/bootstrap/base.html +++ b/djadmin2/templates/djadmin2/bootstrap/base.html @@ -3,7 +3,7 @@ - {% block title %}Site administration{% endblock title %} | django-admin2 + {% block title %}{% trans "Site administration" %}{% endblock title %} | django-admin2 {% block css %} @@ -31,9 +31,7 @@ {% if user.get_full_name %} {{ user.get_full_name }} {% else %} - {% blocktrans with user=user.username %} - Logged in as {{ user }} - {% endblocktrans %} + {% blocktrans with user=user.username %}Logged in as {{ user }}{% endblocktrans %} {% endif %} @@ -54,7 +52,7 @@ {% block breacrumbs %}

    {% endblock breacrumbs %} diff --git a/djadmin2/templates/admin2/bootstrap/includes/app_model_list.html b/djadmin2/templates/djadmin2/bootstrap/includes/app_model_list.html similarity index 100% rename from djadmin2/templates/admin2/bootstrap/includes/app_model_list.html rename to djadmin2/templates/djadmin2/bootstrap/includes/app_model_list.html diff --git a/djadmin2/templates/admin2/bootstrap/index.html b/djadmin2/templates/djadmin2/bootstrap/index.html similarity index 73% rename from djadmin2/templates/admin2/bootstrap/index.html rename to djadmin2/templates/djadmin2/bootstrap/index.html index 11eb551..175927a 100644 --- a/djadmin2/templates/admin2/bootstrap/index.html +++ b/djadmin2/templates/djadmin2/bootstrap/index.html @@ -1,4 +1,4 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load admin2_tags i18n %} {% block content %} @@ -6,7 +6,7 @@
    {% for app_label, registry in apps.items %} - {% include 'admin2/bootstrap/includes/app_model_list.html' %} + {% include 'djadmin2/bootstrap/includes/app_model_list.html' %} {% endfor %}
    diff --git a/djadmin2/templates/admin2/bootstrap/model_confirm_delete.html b/djadmin2/templates/djadmin2/bootstrap/model_confirm_delete.html similarity index 91% rename from djadmin2/templates/admin2/bootstrap/model_confirm_delete.html rename to djadmin2/templates/djadmin2/bootstrap/model_confirm_delete.html index 819fd76..76a58e7 100644 --- a/djadmin2/templates/admin2/bootstrap/model_confirm_delete.html +++ b/djadmin2/templates/djadmin2/bootstrap/model_confirm_delete.html @@ -1,4 +1,4 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load admin2_tags i18n %} {% block title %}{% trans "Are you sure?" %}{% endblock title %} @@ -7,7 +7,7 @@ {% block breadcrumbs %}
  • - Home + {% trans "Home" %} /
  • diff --git a/djadmin2/templates/admin2/bootstrap/model_detail.html b/djadmin2/templates/djadmin2/bootstrap/model_detail.html similarity index 80% rename from djadmin2/templates/admin2/bootstrap/model_detail.html rename to djadmin2/templates/djadmin2/bootstrap/model_detail.html index b115fcf..8434f47 100644 --- a/djadmin2/templates/admin2/bootstrap/model_detail.html +++ b/djadmin2/templates/djadmin2/bootstrap/model_detail.html @@ -1,6 +1,6 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} -{% load admin2_tags %} +{% load admin2_tags i18n %} {% block title %}{{ object }}{% endblock title %} @@ -8,7 +8,7 @@ {% block breadcrumbs %}
  • - Home + {% trans "Home" %} /
  • diff --git a/djadmin2/templates/admin2/bootstrap/model_list.html b/djadmin2/templates/djadmin2/bootstrap/model_list.html similarity index 88% rename from djadmin2/templates/admin2/bootstrap/model_list.html rename to djadmin2/templates/djadmin2/bootstrap/model_list.html index 9c08fee..8df761e 100644 --- a/djadmin2/templates/admin2/bootstrap/model_list.html +++ b/djadmin2/templates/djadmin2/bootstrap/model_list.html @@ -1,4 +1,4 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load admin2_tags i18n %} {% block title %}{% blocktrans with model_name=model_name %}Select {{ model_name }} to change{% endblocktrans %}{% endblock title %} @@ -11,7 +11,7 @@ {% block breadcrumbs %}
  • - Home + {% trans "Home" %} /
  • @@ -28,8 +28,8 @@
    @@ -55,7 +55,9 @@
  • - 0 of {{ object_list|length }} selected + + {% blocktrans with selected='0' total=object_list|length %}{{selected}} of {{total}} selected{% endblocktrans %} +
    {% if permissions.has_add_permission %} {% blocktrans with model_verbose_name=model|model_verbose_name %}Add {{ model_verbose_name }}{% endblocktrans %} @@ -71,7 +73,7 @@ {% if forloop.first and attr == "__str__" %} {{ model_name|capfirst }} {% else %} - {{ attr }} + {{ model|model_attr_verbose_name:attr|capfirst }} {% endif%} {% endfor %} diff --git a/djadmin2/templates/admin2/bootstrap/model_update_form.html b/djadmin2/templates/djadmin2/bootstrap/model_update_form.html similarity index 95% rename from djadmin2/templates/admin2/bootstrap/model_update_form.html rename to djadmin2/templates/djadmin2/bootstrap/model_update_form.html index f9cd750..52c7f7f 100644 --- a/djadmin2/templates/admin2/bootstrap/model_update_form.html +++ b/djadmin2/templates/djadmin2/bootstrap/model_update_form.html @@ -1,4 +1,4 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load admin2_tags i18n %} @@ -8,7 +8,7 @@ {% block breadcrumbs %}
  • - Home + {% trans "Home" %} /
  • diff --git a/djadmin2/templatetags/admin2_tags.py b/djadmin2/templatetags/admin2_tags.py index b54756c..48f45b2 100644 --- a/djadmin2/templatetags/admin2_tags.py +++ b/djadmin2/templatetags/admin2_tags.py @@ -1,4 +1,5 @@ from django import template +from django.db.models.fields import FieldDoesNotExist register = template.Library() @@ -37,6 +38,17 @@ def model_verbose_name_plural(obj): return utils.model_verbose_name_plural(obj) +@register.filter +def model_attr_verbose_name(obj, attr): + """ + Returns the verbose name of a model field or method. + """ + try: + return utils.model_field_verbose_name(obj, attr) + except FieldDoesNotExist: + return utils.model_method_verbose_name(obj, attr) + + @register.filter def formset_visible_fieldlist(formset): """ diff --git a/djadmin2/tests/__init__.py b/djadmin2/tests/__init__.py index 637e13c..a5f20b0 100644 --- a/djadmin2/tests/__init__.py +++ b/djadmin2/tests/__init__.py @@ -3,3 +3,4 @@ from test_types import * from test_utils import * from test_views import * from test_core import * +from test_actions import * diff --git a/djadmin2/tests/test_actions.py b/djadmin2/tests/test_actions.py new file mode 100644 index 0000000..ff11118 --- /dev/null +++ b/djadmin2/tests/test_actions.py @@ -0,0 +1,49 @@ +from django.db import models +from django.test import TestCase + +from ..core import Admin2 +from ..actions import get_description + + +class Thing(models.Model): + pass + + +class TestAction(object): + description = "Test Action Class" + + +def test_function(): + pass + + +class ActionTest(TestCase): + def setUp(self): + self.admin2 = Admin2() + + def test_action_description(self): + self.admin2.register(Thing) + self.admin2.registry[Thing].list_actions.extend([ + TestAction, + test_function, + ]) + self.assertEquals( + get_description( + self.admin2.registry[Thing].list_actions[0] + ), + 'Delete selected items' + ) + self.assertEquals( + get_description( + self.admin2.registry[Thing].list_actions[1] + ), + 'Test Action Class' + ) + self.assertEquals( + get_description( + self.admin2.registry[Thing].list_actions[2] + ), + 'Test function' + ) + self.admin2.registry[Thing].list_actions.remove(TestAction) + self.admin2.registry[Thing].list_actions.remove(test_function) diff --git a/djadmin2/tests/test_admin2tags.py b/djadmin2/tests/test_admin2tags.py index b51bb87..a2c3cfc 100644 --- a/djadmin2/tests/test_admin2tags.py +++ b/djadmin2/tests/test_admin2tags.py @@ -9,6 +9,14 @@ from ..views import IndexView class TagsTestsModel(models.Model): + field1 = models.CharField(max_length=23) + field2 = models.CharField('second field', max_length=42) + + def was_published_recently(self): + return True + was_published_recently.boolean = True + was_published_recently.short_description = 'Published recently?' + class Meta: verbose_name = "Tags Test Model" verbose_name_plural = "Tags Test Models" @@ -58,6 +66,24 @@ class TagsTests(TestCase): admin2_tags.model_verbose_name_plural(self.instance) ) + def test_model_field_verbose_name_autogenerated(self): + self.assertEquals( + 'field1', + admin2_tags.model_attr_verbose_name(self.instance, 'field1') + ) + + def test_model_field_verbose_name_overridden(self): + self.assertEquals( + 'second field', + admin2_tags.model_attr_verbose_name(self.instance, 'field2') + ) + + def test_model_method_verbose_name(self): + self.assertEquals( + 'Published recently?', + admin2_tags.model_attr_verbose_name(self.instance, 'was_published_recently') + ) + def test_formset_visible_fieldlist(self): formset = TagsTestFormSet() self.assertEquals( diff --git a/djadmin2/tests/test_utils.py b/djadmin2/tests/test_utils.py index 2528592..c4f32c1 100644 --- a/djadmin2/tests/test_utils.py +++ b/djadmin2/tests/test_utils.py @@ -7,6 +7,17 @@ from ..views import IndexView class UtilsTestModel(models.Model): + field1 = models.CharField(max_length=23) + field2 = models.CharField('second field', max_length=42) + + def simple_method(self): + return 42 + + def was_published_recently(self): + return True + was_published_recently.boolean = True + was_published_recently.short_description = 'Published recently?' + class Meta: verbose_name = "Utils Test Model" verbose_name_plural = "Utils Test Models" @@ -71,6 +82,30 @@ class UtilsTest(TestCase): utils.model_verbose_name_plural(self.instance) ) + def test_model_field_verbose_name_autogenerated(self): + self.assertEquals( + 'field1', + utils.model_field_verbose_name(self.instance, 'field1') + ) + + def test_model_field_verbose_name_overridden(self): + self.assertEquals( + 'second field', + utils.model_field_verbose_name(self.instance, 'field2') + ) + + def test_model_method_verbose_name(self): + self.assertEquals( + 'Published recently?', + utils.model_method_verbose_name(self.instance, 'was_published_recently') + ) + + def test_model_method_verbose_name_fallback(self): + self.assertEquals( + 'simple_method', + utils.model_method_verbose_name(self.instance, 'simple_method') + ) + def test_app_label_as_model_class(self): self.assertEquals( UtilsTestModel._meta.app_label, diff --git a/djadmin2/utils.py b/djadmin2/utils.py index 3f4256e..fa34af0 100644 --- a/djadmin2/utils.py +++ b/djadmin2/utils.py @@ -22,6 +22,7 @@ def lookup_needs_distinct(opts, lookup_path): return True return False + def model_options(model): """ Wrapper for accessing model._meta. If this access point changes in core @@ -40,18 +41,39 @@ def admin2_urlname(view, action): return 'admin2:%s_%s_%s' % (view.app_label, view.model_name, action) -def model_verbose_name(obj): +def model_verbose_name(model): """ Returns the verbose name of a model instance or class. """ - return model_options(obj).verbose_name + return model_options(model).verbose_name -def model_verbose_name_plural(obj): +def model_verbose_name_plural(model): """ Returns the pluralized verbose name of a model instance or class. """ - return model_options(obj).verbose_name_plural + return model_options(model).verbose_name_plural + + +def model_field_verbose_name(model, field_name): + """ + Returns the verbose name of a model field. + """ + meta = model_options(model) + field = meta.get_field_by_name(field_name)[0] + return field.verbose_name + + +def model_method_verbose_name(model, method_name): + """ + Returns the verbose name / short description of a model field. + """ + meta = model_options(model) + method = getattr(model, method_name) + try: + return method.short_description + except AttributeError: + return method_name def model_app_label(obj): diff --git a/djadmin2/views.py b/djadmin2/views.py index 616ce0d..df9da9f 100644 --- a/djadmin2/views.py +++ b/djadmin2/views.py @@ -4,6 +4,7 @@ from django.contrib.auth.views import (logout as auth_logout, login as auth_login) from django.contrib.auth import get_user_model from django.core.urlresolvers import reverse, reverse_lazy +from django.utils.translation import ugettext_lazy from django.db import models from django.http import HttpResponseRedirect from django.utils.encoding import force_text @@ -25,21 +26,17 @@ from .filters import build_list_filter class IndexView(Admin2Mixin, generic.TemplateView): - """ -Context Variables + """Context Variables - :apps: A dictionary of apps, each app being a dictionary with keys - being models and the value being djadmin2.types.ModelAdmin2 - objects. - - :request.user: The user object representing the current user. + :apps: A dictionary of apps, each app being a dictionary with keys + being models and the value being djadmin2.types.ModelAdmin2 + objects. """ default_template_name = "index.html" registry = None apps = None def get_context_data(self, **kwargs): - data = super(IndexView, self).get_context_data(**kwargs) data.update({ 'apps': self.apps, @@ -65,6 +62,13 @@ class AppIndexView(Admin2Mixin, generic.TemplateView): class ModelListView(AdminModel2Mixin, generic.ListView): + """Context Variables + + :is_paginated: If the page is paginated (page has a next button) + :model: Type of object you are editing + :model_name: Name of the object you are editing + :app_label: Name of your app + """ default_template_name = "model_list.html" permission_classes = ( permissions.IsStaffPermission, @@ -167,6 +171,12 @@ class ModelListView(AdminModel2Mixin, generic.ListView): class ModelDetailView(AdminModel2Mixin, generic.DetailView): + """Context Variables + + :model: Type of object you are editing + :model_name: Name of the object you are editing + :app_label: Name of your app + """ default_template_name = "model_detail.html" permission_classes = ( permissions.IsStaffPermission, @@ -174,6 +184,12 @@ class ModelDetailView(AdminModel2Mixin, generic.DetailView): class ModelEditFormView(AdminModel2Mixin, Admin2ModelFormMixin, extra_views.UpdateWithInlinesView): + """Context Variables + + :model: Type of object you are editing + :model_name: Name of the object you are editing + :app_label: Name of your app + """ form_class = None default_template_name = "model_update_form.html" permission_classes = ( @@ -183,11 +199,17 @@ class ModelEditFormView(AdminModel2Mixin, Admin2ModelFormMixin, extra_views.Upda def get_context_data(self, **kwargs): context = super(ModelEditFormView, self).get_context_data(**kwargs) context['model'] = self.get_model() - context['action'] = "Change" + context['action'] = ugettext_lazy("Change") return context class ModelAddFormView(AdminModel2Mixin, Admin2ModelFormMixin, extra_views.CreateWithInlinesView): + """Context Variables + + :model: Type of object you are editing + :model_name: Name of the object you are editing + :app_label: Name of your app + """ form_class = None default_template_name = "model_update_form.html" permission_classes = ( @@ -197,11 +219,18 @@ class ModelAddFormView(AdminModel2Mixin, Admin2ModelFormMixin, extra_views.Creat def get_context_data(self, **kwargs): context = super(ModelAddFormView, self).get_context_data(**kwargs) context['model'] = self.get_model() - context['action'] = "Add" + context['action'] = ugettext_lazy("Add") return context class ModelDeleteView(AdminModel2Mixin, generic.DeleteView): + """Context Variables + + :model: Type of object you are editing + :model_name: Name of the object you are editing + :app_label: Name of your app + :deletable_objects: Objects to delete + """ success_url = "../../" # TODO - fix this! default_template_name = "model_confirm_delete.html" permission_classes = ( @@ -254,6 +283,10 @@ class PasswordChangeDoneView(Admin2Mixin, generic.TemplateView): class LoginView(Admin2Mixin, generic.TemplateView): + """Context Variables + + :site_name: Name of the site + """ default_template_name = 'auth/login.html' authentication_form = AdminAuthenticationForm @@ -266,6 +299,10 @@ class LoginView(Admin2Mixin, generic.TemplateView): class LogoutView(Admin2Mixin, generic.TemplateView): + """Context Variables + + :site_name: Name of the site + """ default_template_name = 'auth/logout.html' diff --git a/docs/_ext/djangodocs.py b/docs/_ext/djangodocs.py new file mode 100644 index 0000000..a88a9f8 --- /dev/null +++ b/docs/_ext/djangodocs.py @@ -0,0 +1,81 @@ +# Taken from https://github.com/django/django/blob/master/docs/_ext/djangodocs.py + +import re +from sphinx import addnodes + + +# RE for option descriptions without a '--' prefix +simple_option_desc_re = re.compile( + r'([-_a-zA-Z0-9]+)(\s*.*?)(?=,\s+(?:/|-|--)|$)') + + +def setup(app): + app.add_crossref_type( + directivename="setting", + rolename="setting", + indextemplate="pair: %s; setting", + ) + app.add_crossref_type( + directivename="templatetag", + rolename="ttag", + indextemplate="pair: %s; template tag" + ) + app.add_crossref_type( + directivename="templatefilter", + rolename="tfilter", + indextemplate="pair: %s; template filter" + ) + app.add_crossref_type( + directivename="fieldlookup", + rolename="lookup", + indextemplate="pair: %s; field lookup type", + ) + app.add_description_unit( + directivename="django-admin", + rolename="djadmin", + indextemplate="pair: %s; django-admin command", + parse_node=parse_django_admin_node, + ) + app.add_description_unit( + directivename="django-admin-option", + rolename="djadminopt", + indextemplate="pair: %s; django-admin command-line option", + parse_node=parse_django_adminopt_node, + ) + + +def parse_django_admin_node(env, sig, signode): + command = sig.split(' ')[0] + env._django_curr_admin_command = command + title = "django-admin.py %s" % sig + signode += addnodes.desc_name(title, title) + return sig + + +def parse_django_adminopt_node(env, sig, signode): + """A copy of sphinx.directives.CmdoptionDesc.parse_signature()""" + from sphinx.domains.std import option_desc_re + count = 0 + firstname = '' + for m in option_desc_re.finditer(sig): + optname, args = m.groups() + if count: + signode += addnodes.desc_addname(', ', ', ') + signode += addnodes.desc_name(optname, optname) + signode += addnodes.desc_addname(args, args) + if not count: + firstname = optname + count += 1 + if not count: + for m in simple_option_desc_re.finditer(sig): + optname, args = m.groups() + if count: + signode += addnodes.desc_addname(', ', ', ') + signode += addnodes.desc_name(optname, optname) + signode += addnodes.desc_addname(args, args) + if not count: + firstname = optname + count += 1 + if not firstname: + raise ValueError + return firstname diff --git a/docs/_static/README b/docs/_static/README new file mode 100644 index 0000000..7fd9945 --- /dev/null +++ b/docs/_static/README @@ -0,0 +1 @@ +Put static files for Sphinx in here. diff --git a/docs/architecture.rst b/docs/architecture.rst deleted file mode 100644 index d349c9b..0000000 --- a/docs/architecture.rst +++ /dev/null @@ -1,22 +0,0 @@ -================ -Architecture -================ - -.. warning:: This is out of date and will be updated shortly. - -Workflow Pieces ----------------- - -* Apps -* Apps.models -* AdminObj -* Appstore - -Workflow ----------------- - -1. Instantiate Appstore -2. Loop through the Apps then models per App -3. Admin2s are created from models: djadmin2.models.register(Poll) -4. Admin2s contain methods/properties necessaey for UI -5. Views diff --git a/docs/conf.py b/docs/conf.py index d843649..17fb2a2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,7 +11,8 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import os +import sys # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -32,6 +33,10 @@ from example.example import settings from django.core.management import setup_environ setup_environ(settings) +# For intersphinx +ext_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "_ext")) +sys.path.append(ext_path) + # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. @@ -39,7 +44,8 @@ setup_environ(settings) # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx'] +extensions = ['djangodocs', 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', +'sphinx.ext.todo'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -62,9 +68,9 @@ copyright = u'2013, Daniel Greenfeld' # built documents. # # The short X.Y version. -version = '0.4' +version = '0.5' # The full version, including alpha/beta/rc tags. -release = '0.4.0' +release = '0.5.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -264,7 +270,9 @@ texinfo_documents = [ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { + 'python': ('http://python.readthedocs.org/en/v2.7.2/', None), 'django': ( 'http://docs.djangoproject.com/en/dev/', - 'http://docs.djangoproject.com/en/dev/_objects/'), + 'http://docs.djangoproject.com/en/dev/_objects/' + ), } diff --git a/docs/contributing.rst b/docs/contributing.rst index 1e8df25..36509ce 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -27,7 +27,7 @@ Local Installation 1. Create a virtualenv_ (or use virtualenvwrapper_). Activate it. 2. cd into django-admin2 3. type ``$ pip install -r requirements.txt`` -4. type ``$ python setup.py develop`` +4. type ``$ python setup.py develop`` Try the example projects -------------------------- @@ -37,7 +37,7 @@ Try the example projects 3. run the dev server: ``$ python manage.py runserver`` .. _virtualenv: http://www.virtualenv.org/en/latest/ -.. _virtualenvwrapper: http://virtualenvwrapper.readthedocs.org/en/latest/ +.. _virtualenvwrapper: http://virtualenvwrapper.readthedocs.org/en/latest/ Issues! ======= @@ -61,7 +61,7 @@ Setting up topic branches and generating pull requests While it's handy to provide useful code snippets in an issue, it is better for you as a developer to submit pull requests. By submitting pull request your -contribution to django-admin2 will be recorded by Github. +contribution to django-admin2 will be recorded by Github. In git it is best to isolate each topic or feature into a "topic branch". While individual commits allow you control over how small individual changes are made @@ -113,23 +113,24 @@ add a comment to the discussion section of the pull request. Pull upstream changes into your fork regularly ================================================== -**django-admin2** is advancing quickly. It is therefore critical that you pull upstream changes from master into your fork on a regular basis. Nothing is worse than putting in a day of hard work into a pull request only to have it rejected because it has diverged too far from master. +**django-admin2** is advancing quickly. It is therefore critical that you pull upstream changes from master into your fork on a regular basis. Nothing is worse than putting in a day of hard work into a pull request only to have it rejected because it has diverged too far from master. To pull in upstream changes:: git remote add upstream https://github.com/twoscoops/django-admin2.git - git fetch upstream develop - -Check the log to be sure that you actually want the changes, before merging:: - - git log upstream/develop - -Then merge the changes that you fetched:: - - git merge upstream/develop + git pull upstream develop For more info, see http://help.github.com/fork-a-repo/ +Advanced git users: Pull with rebase +------------------------------------ + +This will pull and then reapply your work on top of the upcoming changes:: + + git pull --rebase upstream develop + +It saves you from an extra merge, keeping the history cleaner, but it's potentially dangerous because you're rewriting history. For more info, see http://gitready.com/advanced/2009/02/11/pull-with-rebase.html + How to get your pull request accepted ===================================== @@ -207,7 +208,7 @@ As much as possible, we follow the advice of the `Two Scoops of Django`_ book. P Templates ~~~~~~~~~ -Follow bootstrap's coding standards for HTML_ and CSS_. Use two spaces for indentation, and write so the templates are readable (not for the generated html). +Follow bootstrap's coding standards for HTML_ and CSS_. Use two spaces for indentation, and write so the templates are readable (not for the generated html). .. _HTML: https://github.com/twitter/bootstrap/blob/master/CONTRIBUTING.md#coding-standards-html .. _CSS: https://github.com/twitter/bootstrap/blob/master/CONTRIBUTING.md#coding-standards-css diff --git a/docs/index.rst b/docs/index.rst index 4864518..e20f701 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,29 +1,33 @@ +========================================= Welcome to django-admin2's documentation! ========================================= +.. image:: https://travis-ci.org/pydanny/django-admin2.png + :alt: Build Status + :target: https://travis-ci.org/pydanny/django-admin2 + +**Warning:** This project is currently in an **alpha** state and currently not meant for real projects. + +One of the most useful parts of ``django.contrib.admin`` is the ability to configure various views that touch and alter data. django-admin2 is a complete rewrite of that library using modern Class-Based Views and enjoying a design focused on extendibility and adaptability. By starting over, we can avoid the legacy code and make it easier to write extensions and themes. + **django-admin2** aims to replace django's built-in admin that lives in -``django.contrib.admin``. Come and help us, have a look at the -:doc:`contributing` page and see our `GitHub`_ page. +``django.contrib.admin``. Come and help us, read the :doc:`design` and +:doc:`contributing` pages, and visit the `GitHub`_ project. This project is intentionally backwards-incompatible with ``django.contrib.admin``. -Requirements +Features ============= -* Django 1.5+ -* Python 2.7+ or Python 3.3+ -* django-braces -* django-extra-views -* django-floppyforms -* django-rest-framework -* Sphinx (for documentation) - +* Rewrite of the Django Admin backend +* Drop-in themes +* Built-in RESTful API Basic API ============== -Our goal is to make this API work: +If you've worked with Django, this implementation should look familiar: .. code-block:: python @@ -56,34 +60,30 @@ Content .. toctree:: :maxdepth: 2 + installation contributing design - architecture - api - themes - built-in-views - meta tutorial + internationalization Reference ----------- -Most of django-admin2 is designed to be extensible, which means with a little bit of Python code you can do amazing things. You can easily create custom actions, implement alternative forms, set permissions per view, add new views, and even trivially replace the base views with those of your own design. Combined with the REST API, django-admin2 provides a wealth of customization options. - -One of the core design goals of django-admin2 is to embrace object-oriented design, making it easy to take one of the built-in classes and extend it to suit your needs. - .. toctree:: :maxdepth: 2 + ref/themes + ref/api ref/actions ref/forms ref/permissions ref/views + ref/built-in-views + ref/meta Indices and tables ================== * :ref:`genindex` -* :ref:`modindex` * :ref:`search` diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..0eb0cb4 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,48 @@ +============ +Installation +============ + +.. index:: installation + +Adding django-admin2 to your project +==================================== + + +Use pip to install from PyPI: + +.. code-block:: python + + pip install django-admin2 + +Add djadmin2 and rest_framework to your settings file: + +.. code-block:: python + + INSTALLED_APPS = ( + ... + 'djadmin2', + 'rest_framework', # for the browsable API templates + ... + ) + +Add djadmin2 urls to your URLconf: + +.. code-block:: python + + # urls.py + from django.conf.urls import patterns, include + + import djadmin2 + + djadmin2.default.autodiscover() + + + urlpatterns = patterns( + ... + url(r'^admin2/', include(djadmin2.default.urls)), + ) + +Development Installation +========================= + +See :doc:`contributing`. diff --git a/docs/internationalization.rst b/docs/internationalization.rst new file mode 100644 index 0000000..f904dd2 --- /dev/null +++ b/docs/internationalization.rst @@ -0,0 +1,83 @@ +===================================== +Internationalization and localization +===================================== + +.. index:: internationalization + +Refer to the `Django i18n documentation`_ to get started. + +.. _`Django i18n documentation`: https://docs.djangoproject.com/en/dev/topics/i18n/ + + +Using internationalization in your project +========================================== + +Make sure you've activated translation for your project +(the fastest way is to check in your ``settings.py`` file if ``MIDDLEWARE_CLASSES`` includes +``django.middleware.locale.LocaleMiddleware``). + +Then compile the messages so they can be used by Django. + +.. code-block:: bash + + python manage.py compilemessages + + +It should get you started ! + +Contributing to localization +============================ + +Django-admin2 has adopted `Transifex`_ to manage the localization process, `join and +help us`_ making django-admin2 available for everyone ! + +.. _Transifex: https://www.transifex.com +.. _`join and help us`: https://www.transifex.com/projects/p/django-admin2/ + + +Using internationalization in the django-admin2 project development +=================================================================== + +Internationalization +-------------------- + +Python code +########### + +Make sure to use ugettext or ugettext_lazy on strings that will be shown to the users, +with string interpolation ( "%(name_of_variable)s" instead of "%s" ) where needed. + +Remember that all languages do not use the same word order, so try to provide flexible strings to translate ! + +Templates +######### + +Make sure to load the i18n tags and put ``trans`` tags and ``blocktrans`` blocks where needed. + +Block variables are very useful to keep the strings simple. + +Adding a new locale +------------------- + +.. code-block:: bash + + cd djadmin2 + django-admin.py makemessages -l $LOCALE_CODE + +A new file will be created under ``locale/$LOCALE_CODE/LC_MESSAGES/django.po`` + +Update the headers of the newly created file to match existing files and start the translation ! + + +Updating existing locales +------------------------- + +.. code-block:: bash + + cd djadmin2 # or any other package, for instance example/blog + django-admin.py makemessages -a + + # update the translations + # make sure to fix all fuzzy translations + + django-admin.py compilemessages diff --git a/docs/ref/actions.rst b/docs/ref/actions.rst index 440b0d1..42eaa8e 100644 --- a/docs/ref/actions.rst +++ b/docs/ref/actions.rst @@ -2,6 +2,8 @@ Actions ======= +.. index:: Actions + Actions are defined to work on a single view type. Currently, actions are only implemented against the ``ModelListView``. This view contains the default ``DeleteSelectedAction`` method, which in end functionality mirrors ``django.contrib.admin.delete_selected``. However, under the hood, django-admin2's actions work very differently. Instead of functions with assigned attributes, they can either be functions or full fledged objects. Which means you can more easily extend them to suit your needs. @@ -39,6 +41,9 @@ The documentation works off a simple set of models, as listed below: Writing List Actions ----------------------- +.. index:: + single: Actions; Writing List Actions + The basic workflow of Django’s admin is, in a nutshell, “select an object, then change it.” This works well for a majority of use cases. However, if you need to make the same change to many objects at once, this workflow can be quite tedious. In these cases, Django’s admin lets you write and register “actions” – simple functions that get called with a list of objects selected on the change list page. diff --git a/docs/api.rst b/docs/ref/api.rst similarity index 95% rename from docs/api.rst rename to docs/ref/api.rst index 78ae92c..5ffc930 100644 --- a/docs/api.rst +++ b/docs/ref/api.rst @@ -1,5 +1,5 @@ -API -=== +RESTful API +============= **django-admin2** comes with a builtin REST-API for accessing all the resources you can get from the frontend via JSON. diff --git a/docs/built-in-views.rst b/docs/ref/built-in-views.rst similarity index 66% rename from docs/built-in-views.rst rename to docs/ref/built-in-views.rst index 0880299..5baf711 100644 --- a/docs/built-in-views.rst +++ b/docs/ref/built-in-views.rst @@ -1,12 +1,27 @@ Built-In Views =============== -Each of these views contains the list of context variables that are included in their templates. +Each of these views contains the list of context variables that are included in +their templates. -TODO: Provide a list of template context variables for each view per GitHub issue in view class' top-level docstring `#220`_ +TODO: Provide a list of template context variables for each view per GitHub +issue in view class' top-level docstring `#220`_ .. _`#220`: https://github.com/twoscoops/django-admin2/issues/220 +View Constants +--------------- + +The following are available in every view: + + :next: The page to redirect the user to after login + :MEDIA_URL: Specify a directory where file uploads for users who use your site go + :STATIC_URL: Specify a directory for JavaScript, CSS and image files. + :user: Currently logged in user + +View Descriptions +------------------ + .. autoclass:: djadmin2.views.IndexView :members: @@ -27,11 +42,9 @@ TODO: Provide a list of template context variables for each view per GitHub issu .. autoclass:: djadmin2.views.ModelAddFormView :members: - .. autoclass:: djadmin2.views.ModelDeleteView :members: - .. autoclass:: djadmin2.views.PasswordChangeView :members: diff --git a/docs/meta.rst b/docs/ref/meta.rst similarity index 96% rename from docs/meta.rst rename to docs/ref/meta.rst index d54b050..926c8fd 100644 --- a/docs/meta.rst +++ b/docs/ref/meta.rst @@ -48,7 +48,8 @@ Attributes copied from ``Meta`` Some of ``_meta``'s attributes are just copied from the ``Meta`` options. The following attributes are those. Their behaviour is more detailed described in -the :doc:`django documentation `. +the `django documentation +`__. ``abstract`` A boolean value. @@ -87,7 +88,9 @@ the :doc:`django documentation `. :attr:`~django.db.models.Options.get_latest_by`. ``managed`` - If ``managed`` is ``True`` then the :djadmin:`syncdb` management command will take care of creating the database tables. Defaults to ``True``. + If ``managed`` is ``True`` then the :django:djadmin:`syncdb` management + command will take care of creating the database tables. Defaults to + ``True``. Also see the django documentation about :attr:`~django.db.models.Options.managed`. diff --git a/docs/ref/permissions.rst b/docs/ref/permissions.rst index 4d0b106..5b11403 100644 --- a/docs/ref/permissions.rst +++ b/docs/ref/permissions.rst @@ -1,6 +1,8 @@ Permissions =========== +.. index:: Permissions + Permissions are handled on a per view basis. So basically each admin view can hold its own permissions. That way you are very flexible in defining who is allowed to access which view. For example, the edit view might need some @@ -28,8 +30,11 @@ attribute: See the following sections on which permission classes ship with **django-admin2**, ready to use and how you can roll your own. -Builtin permission classes --------------------------- +Built-in permission classes +--------------------------- + +.. index:: + single: Permissions; Built-In Permission Classes You can use the following permission classes directly in you views. @@ -48,6 +53,9 @@ You can use the following permission classes directly in you views. Writing your own permission class --------------------------------- +.. index:: + single: Permissions; Custom Permission Classes + If you need it, writing your own permission class is really easy. You just need to subclass the :class:`djadmin2.permissions.BasePermission` class and overwrite the :meth:`~djadmin2.permissions.BasePermission.has_permission` @@ -89,9 +97,12 @@ Here is an example implementation of a custom permission class: return False return True -Permissions in templates +Permissions in Templates ------------------------ +.. index:: + single: Permissions; Permissions in Templates + Since the permission handling is designed around views, the permission checks in the template will also always access a view and return either ``True`` or ``False`` if the user has access to the given view. There is a ``{{ permissions @@ -128,9 +139,12 @@ At the moment we can check for the following four basic permissions: ``has_delete_permission`` This will check the permissions against the current admin's ``delete_view``. -Object-level permissions +Object-Level Permissions ~~~~~~~~~~~~~~~~~~~~~~~~ +.. index:: + single: Permissions; Object-Level Permissions + The permission handling in templates also support checking for object-level permissions. To do so, you can use the ``for_object`` filter implemented in the ``admin2_tags`` templatetag library: @@ -181,9 +195,12 @@ permissions as well: {% include "list_of_model_actions.html" with permissions=object_permissions %} {% endwith %} -Checking for permissions on other models +Checking for Permissions on Other Models ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. index:: + single: Permissions; Checking for Permissions on Other Models + Sometimes you just need to check the permissions for that particular model. In that case, you can access its permissions like this: @@ -214,9 +231,12 @@ to a model admin, you can use the ``for_admin`` filter: {% endwith %} {% endfor %} -Dynamically check for a specific permission name +Dynamically Check for a Specific Permission Name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. index:: + single: Permissions; Dynamically Check for a Specific Permission Name + Just like you can bind a permission dynamically to a model admin, you can also specify the actual permission name on the fly. There is the ``for_view`` filter to do so. diff --git a/docs/themes.rst b/docs/ref/themes.rst similarity index 97% rename from docs/themes.rst rename to docs/ref/themes.rst index 3a00aba..7180230 100644 --- a/docs/themes.rst +++ b/docs/ref/themes.rst @@ -138,12 +138,12 @@ In the settings module, place the theme right after djadmin2 (change the highlig ) ########### END DJANGO-ADMIN2 CONFIGURATION -.. TODO:: Have someone besides pydanny test this! +.. todo:: Have someone besides pydanny test this! Views and their Templates ------------------------- -See :ref:`Built-In Views` +See doc:`built-in-views` Available Themes @@ -156,4 +156,4 @@ If you'd like to experiment with UI design that differs from the original Django Future ------ -Keep in mind that this project is an experiment just to get our ideas down. We are looking at other similar projects to see if we can merge or borrow things. \ No newline at end of file +Keep in mind that this project is an experiment just to get our ideas down. We are looking at other similar projects to see if we can merge or borrow things. diff --git a/example/blog/actions.py b/example/blog/actions.py index 8603b3c..07900f5 100644 --- a/example/blog/actions.py +++ b/example/blog/actions.py @@ -11,7 +11,7 @@ class CustomPublishAction(BaseListAction): ) description = ugettext_lazy('Publish selected items') - success_message = 'Successfully published %d %s' + success_message = ugettext_lazy('Successfully published %(count)s %(items)s') default_template_name = "actions/publish_selected_items.html" diff --git a/example/blog/templates/base.html b/example/blog/templates/base.html new file mode 100644 index 0000000..62f9c02 --- /dev/null +++ b/example/blog/templates/base.html @@ -0,0 +1,30 @@ +{% load i18n %} + + + + + Example.com + + + {% block css %} + + + {% endblock css %} + + +
    +
    +
    +

    +
    +
    + {% block content %}{% endblock content %} +
    + + {% block javascript %} + + + + {% endblock javascript %} + + diff --git a/example/blog/templates/blog/home.html b/example/blog/templates/blog/home.html index 8609179..9a765c0 100644 --- a/example/blog/templates/blog/home.html +++ b/example/blog/templates/blog/home.html @@ -1,10 +1,48 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "base.html" %} +{% load staticfiles %} {% block content %} -

    Example Home

    +
    +
    +

    Example.com

    - +

    Imagine that this is a real site

    + +

    Pretend that this is the homepage of a big Django site.

    + +

    Imagine lots of things are here:

    +
      +
    • A blog
    • +
    • Comments
    • +
    • And so on...
    • +
    + +

    In other words, these are items that we can introspect through the Django admin.

    + +

    Under the hood

    + +

    Now, explore the Django admin for example.com. Click on either of the following:

    +
    +
    + +
    +
    +

    The original Django Admin

    + + + + + +

    Powered by django.contrib.admin. This is just here for reference.

    +
    +
    +

    The new Admin2

    + + + + + +

    Powered by django-admin2.

    +
    +
    {% endblock %} \ No newline at end of file diff --git a/example/blog/templates/admin2/bootstrap/actions/publish_selected_items.html b/example/blog/templates/djadmin2/bootstrap/actions/publish_selected_items.html similarity index 96% rename from example/blog/templates/admin2/bootstrap/actions/publish_selected_items.html rename to example/blog/templates/djadmin2/bootstrap/actions/publish_selected_items.html index 988e435..9cf329d 100644 --- a/example/blog/templates/admin2/bootstrap/actions/publish_selected_items.html +++ b/example/blog/templates/djadmin2/bootstrap/actions/publish_selected_items.html @@ -1,4 +1,4 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% load admin2_tags i18n %} {% block title %}Are you sure?{% endblock title %} diff --git a/example/example/settings.py b/example/example/settings.py index 6d91c87..8dfb0e9 100644 --- a/example/example/settings.py +++ b/example/example/settings.py @@ -1,4 +1,7 @@ # Django settings for example project. +import os + +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) DEBUG = True TEMPLATE_DEBUG = DEBUG @@ -67,6 +70,7 @@ STATICFILES_DIRS = ( # Put strings here, like "/home/html/static" or "C:/www/django/static". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. + os.path.join(BASE_DIR, "static"), ) # List of finder classes that know how to find static files in @@ -89,6 +93,7 @@ TEMPLATE_LOADERS = ( MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', + 'django.middleware.locale.LocaleMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -157,7 +162,7 @@ LOGGING = { } -ADMIN2_THEME_DIRECTORY = "admin2/bootstrap/" +ADMIN2_THEME_DIRECTORY = "djadmin2/bootstrap/" ########## TOOLBAR CONFIGURATION diff --git a/example/static/img/admin.png b/example/static/img/admin.png new file mode 100644 index 0000000..da0ac0b Binary files /dev/null and b/example/static/img/admin.png differ diff --git a/example/static/img/admin2.png b/example/static/img/admin2.png new file mode 100644 index 0000000..2424370 Binary files /dev/null and b/example/static/img/admin2.png differ diff --git a/example2/example2/settings.py b/example2/example2/settings.py index 3b0a275..bb1df97 100644 --- a/example2/example2/settings.py +++ b/example2/example2/settings.py @@ -88,6 +88,7 @@ TEMPLATE_LOADERS = ( ) MIDDLEWARE_CLASSES = ( + 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', @@ -124,6 +125,14 @@ INSTALLED_APPS = ( 'polls', ) +try: + import django_extensions + INSTALLED_APPS += ( + 'django_extensions', + ) +except ImportError: + pass + # A sample logging configuration. The only tangible logging # performed by this configuration is to send an email to # the site admins on every HTTP 500 error when DEBUG=False. @@ -154,4 +163,24 @@ LOGGING = { } -ADMIN2_THEME_DIRECTORY = "admin2/bootstrap/" +ADMIN2_THEME_DIRECTORY = "djadmin2/bootstrap/" + +########## TOOLBAR CONFIGURATION +# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation +INSTALLED_APPS += ( + 'debug_toolbar', +) + +# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation +INTERNAL_IPS = ('127.0.0.1',) + +# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation +MIDDLEWARE_CLASSES += ( + 'debug_toolbar.middleware.DebugToolbarMiddleware', +) + +DEBUG_TOOLBAR_CONFIG = { + 'INTERCEPT_REDIRECTS': False, + 'SHOW_TEMPLATE_CONTEXT': True, +} +########## END TOOLBAR CONFIGURATION diff --git a/example2/polls/templates/home.html b/example2/polls/templates/home.html index f00243e..d16e212 100644 --- a/example2/polls/templates/home.html +++ b/example2/polls/templates/home.html @@ -1,4 +1,4 @@ -{% extends "admin2/bootstrap/base.html" %} +{% extends "djadmin2/bootstrap/base.html" %} {% block content %}

    Example Home