1

Django 管理者のリスト表示に絶対 URI を表示しようとしています。

from django.contrib import admin
class MyAdmin(admin.ModelAdmin):
    list_display = (
        'full_uri',
    )

    readonly_fields = (
        'full_uri',
    )

    def full_uri(self, obj):
        return u'<a href="{url}">{url}'.format(
            url = request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
        )
    full_uri.allow_tags = True

build_absolute_uri問題 - (定義されている) リクエスト オブジェクトにアクセスできません。

changelist_viewリクエストのローカルをオーバーライドして保存しようとしましたが、これはスレッドセーフではありません。

私もこのソリューションを試しましたが、あまりエレガントではありません。

他のアイデアはありますか?

編集:

これは安全な解決策ですか:

def changelist_view(self, request, extra_context=None):
    self.request = request
    try:
        return super(MyAdmin,self).changelist_view(request, extra_context=extra_context)
    finally:
        self.request = None

EDIT2:

スレッドセーフではありません。1 2 , ...

4

3 に答える 3

3

admin.ModelAdmin を拡張するすべてのクラスには、オーバーライド可能な 2 つの関数、change_view と changelist_view が付属しています。 change_view単一のインスタンスを編集するときにchangelist_view呼び出され、すべてのアイテムのリストを表示するときに呼び出されます。

これらの 2 つの関数は、管理者のビュー定義として機能し、ページの要求オブジェクトを含みます。これは、これら 2 つselfの関数内で、そのビューから呼び出されたクラス内の他の関数からアクセスできるようにするために、要求を のプロパティとして保存できることを意味します。そうは言っても、次のようなものが機能するはずです。

from django.contrib import admin
class MyAdmin(admin.ModelAdmin):
list_display = (
    'full_uri',
)

readonly_fields = (
    'full_uri',
)

def change_view(self, request, object_id, form_url='', extra_context=None):
    # access the request object when in the change view
    self.request = request
    return super(MyAdmin, self).change_view(request, object_id, form_url=form_url, extra_context=extra_context)

def changelist_view(self, request, extra_context=None):
    # access the request object when in the list view
    self.request = request
    return super(MyAdmin,self).changelist_view(request, extra_context=extra_context)

def full_uri(self, obj):
    return u'<a href="{url}">{url}'.format(
        # access the request object through self.request, as set by the two view functions
        url = self.request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
    )
full_uri.allow_tags = True
于 2013-03-12T21:52:04.643 に答える
1

私はスレッドセーフな方法でそれを行う方法を見つけたと思います、内部に関数を作成しますget_list_display

def get_list_display(self, request):

   def link_to_view(obj):
        return u'<a href="{url}">{url}'.format(
            url = request.build_absolute_uri(reverse('view_name', args=(obj, )))
        )
    token_access_link.short_description = _('link')
    token_access_link.allow_tags = True

    return (
        link_to_view,
    )
于 2013-03-14T13:17:47.117 に答える
0

私が質問を正しく理解していれば、送信されていない関数内のリクエスト オブジェクトにアクセスする必要があるだけですか?

もしそうなら、私はdjango-globalsが現在のリクエストとユーザーへのユニバーサルアクセスを提供するので最も役立つことを発見しました (フラスコのようにデフォルトでアクセスできるはずです!)

pip install django-globals

設定.py

INSTALLED_APPS = [
   ...
   'django_globals'
]
MIDDLEWARE_CLASSES = [
    ...
    'django_globals.middleware.Global'
]

view.py

from django_globals import globals as djglobals

def myfunc():
    djglobals.user
    djglobals.request
于 2016-04-13T04:34:28.727 に答える