Différences entre versions de « Django »

De Cliss XXI
Sauter à la navigation Sauter à la recherche
imported>SylvainBeucler
m (personnaliser l'interface d'admin)
 
imported>SylvainBeucler
m (Accès à la requête courante)
 
(5 versions intermédiaires par le même utilisateur non affichées)
Ligne 4 : Ligne 4 :
 
* [http://lincolnloop.com/blog/2009/jun/22/customizing-django-admin-eurodjangocon-2009/ Customizing the Django Admin at EuroDjangoCon 2009]
 
* [http://lincolnloop.com/blog/2009/jun/22/customizing-django-admin-eurodjangocon-2009/ Customizing the Django Admin at EuroDjangoCon 2009]
 
* [http://lincolnloop.com/assets/Customizing_the_Django_Admin-EuroDjangoCon09.pdf Customizing_the_Django_Admin-EuroDjangoCon09.pdf]
 
* [http://lincolnloop.com/assets/Customizing_the_Django_Admin-EuroDjangoCon09.pdf Customizing_the_Django_Admin-EuroDjangoCon09.pdf]
 +
* [http://code.djangoproject.com/wiki/CookBookNewformsAdminAndUser CookBookNewformsAdminAndUser]
 +
* [http://www.ibm.com/developerworks/opensource/library/os-django-admin/index.html Doing more with the Django admin]
 +
* [http://joshourisman.com/2009/10/15/django-admin-awesomeness/ Django admin awesomeness]: vue alternative avec un ModelAdmin dérivé
 +
Modifier le queryset dynamiquement:
 +
<pre>
 +
class StuffAdmin(admin.ModelAdmin)
 +
    ...
 +
    def queryset(self, request):
 +
        qs = super(self.__class__, self).queryset(request)
 +
        qs = qs.filter(user=request.user)
 +
        return qs
 +
 +
    # or
 +
    def queryset(self, request):
 +
        qs = self.model._default_manager.filter(user=request.user)
 +
        return qs
 +
</pre>
 +
 +
Forcer des champs dynamiquement:
 +
<pre>
 +
class StuffAdmin(admin.ModelAdmin)
 +
    ...
 +
    def save_model(self, request, object, form, change):
 +
        object.user = request.user
 +
        object.save()
 +
</pre>
 +
 +
== Accès à la requête courante ==
 +
 +
<pre>
 +
# -*- coding: utf-8 -*-
 +
# Passe la requête courante en variable "globale"
 +
# Copyright (C) 2010  Cliss XXI
 +
#
 +
# This is free software: you can redistribute it and/or modify it
 +
# under the terms of the GNU Affero General Public License as
 +
# published by the Free Software Foundation, either version 3 of the
 +
# License, or (at your option) any later version.
 +
#
 +
# This file is distributed in the hope that it will be useful, but
 +
# WITHOUT ANY WARRANTY; without even the implied warranty of
 +
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +
# Affero General Public License for more details.
 +
#
 +
# You should have received a copy of the GNU Affero General Public License
 +
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 +
#
 +
# Author: Sylvain Beucler
 +
 +
"""
 +
Some people apparently cannot stand thread locals, to the point they
 +
censor and block wiki pages:
 +
http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser
 +
http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser?action=diff&version=19
 +
Another link:
 +
http://lucumr.pocoo.org/2006/7/10/why-i-cant-stand-threadlocal-and-others
 +
 +
Passing the current request is perfectly legitimate for
 +
request-specific code such as web forms.
 +
 +
Passing other kind of data around might not be, but that's something
 +
to decide on a per-case basis.
 +
"""
 +
 +
from threading import local
 +
 +
# Must call local() once, each call returns a different (empty) object
 +
_cur_thread_local = local()
 +
 +
def get_current_request():
 +
    try:
 +
        return _cur_thread_local.request
 +
    except:
 +
        from django.core.exceptions import ImproperlyConfigured
 +
        raise ImproperlyConfigured("Add threadlocals.ThreadLocals in your MIDDLEWARE_CLASSES setting")
 +
 +
class ThreadLocals(object):
 +
    def process_request(self, request):
 +
        _cur_thread_local.request = request
 +
        return None  # Continue processing
 +
</pre>
 +
 +
== Liens ==
 +
 +
* [http://www.mercurytide.co.uk/news/article/django-cheat-sheet/ Fiche de triche Django]

Version actuelle datée du 18 mars 2010 à 14:43

Personnaliser l'interface d'admin

De quoi aller plus loin, principalement les quelques derniers slides (ce sont des choses que j'avais cherché pendant trois plombes):

Modifier le queryset dynamiquement:

class StuffAdmin(admin.ModelAdmin)
    ...
    def queryset(self, request):
        qs = super(self.__class__, self).queryset(request)
        qs = qs.filter(user=request.user)
        return qs

    # or
    def queryset(self, request):
        qs = self.model._default_manager.filter(user=request.user)
        return qs

Forcer des champs dynamiquement:

class StuffAdmin(admin.ModelAdmin)
    ...
    def save_model(self, request, object, form, change):
        object.user = request.user
        object.save()

Accès à la requête courante

# -*- coding: utf-8 -*-
# Passe la requête courante en variable "globale"
# Copyright (C) 2010  Cliss XXI
#
# This is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Affero General Public License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 
# Author: Sylvain Beucler

"""
Some people apparently cannot stand thread locals, to the point they
censor and block wiki pages:
http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser
http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser?action=diff&version=19
Another link:
http://lucumr.pocoo.org/2006/7/10/why-i-cant-stand-threadlocal-and-others

Passing the current request is perfectly legitimate for
request-specific code such as web forms.

Passing other kind of data around might not be, but that's something
to decide on a per-case basis.
"""

from threading import local

# Must call local() once, each call returns a different (empty) object
_cur_thread_local = local()

def get_current_request():
    try:
        return _cur_thread_local.request
    except:
        from django.core.exceptions import ImproperlyConfigured
        raise ImproperlyConfigured("Add threadlocals.ThreadLocals in your MIDDLEWARE_CLASSES setting")

class ThreadLocals(object):
    def process_request(self, request):
        _cur_thread_local.request = request
        return None  # Continue processing

Liens