将Django基于类的视图添加到管理站点

3

我使用基于类的视图创建了一些表单,现在我想将它们添加到Django管理站点中。我只找到了这个链接,其中描述了如何将普通视图添加到管理站点。


4
欢迎来到SO。准备好被踩到底了。 :) 请阅读这些关于如何提出详细、有用问题的指南 - grill
这个话题实际上很有趣,但你通过问“什么都没有”把它搞反了...@PhilippWiesner,建议:只需实现你在链接中阅读到的内容。 - Yeo
所以,也许这才是你真正的问题 ;) https://dev59.com/EIrda4cB1Zd3GeqPNo3X - Yeo
是的,这两个问题是相互关联的,因为这是我遇到的第一个问题。 - Philipp Wiesner
4个回答

8

假设您有以下基于类的视图:

# File: views.py
class MyAwesomeBookView(TemplateView):
    pass

要使用此视图,您需要使其成为可调用

# File: views.py
awesome_book_view = MyAwesomeBookView.as_view()

一旦您的视图是callable,您可以将其视为类似于基于函数的视图的处理方式。

要将其链接到管理URL,您可以执行以下操作:

# File: admin.py
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):

    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            url(r'^awesome-books/$', 
                self.admin_site.admin_view(awesome_book_view)),
        ]
        return my_urls + urls

5

为了与Django管理模板进行完整的集成,您可以将模型管理器作为额外参数传递给基于类的视图,然后使用它来向上下文(context)添加一些更好的内容:

文件 admin.py:

from django.contrib import admin
from .models import MyModel
from .views import ProcessObjectView

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):

    def get_urls(self):
        info = self.model._meta.app_label, self.model._meta.model_name
        urls = super().get_urls()
        my_urls = patterns('',
            url(r'^(?P<object_id>.*)/process/$',
                self.admin_site.admin_view(ProcessObjectView.as_view()),
                {'model_admin': self, },
                name="%s_%s_process" % info),
        )
        return my_urls + urls

文件 views.py

from django.contrib.auth import get_permission_codename

class ProcessObjectView(UpdateView):

    model = MyModel
    pk_url_kwarg = "object_id"
    fields = [... ]
    template_name = 'admin/backend/mymodel/process_object.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # see http://www.slideshare.net/lincolnloop/customizing-the-django-admin
        model_admin = self.kwargs['model_admin']
        opts = model_admin.model._meta
        admin_site = model_admin.admin_site
        has_perm = self.request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts))
        context.update({
            'admin_site': admin_site.name,
            'title': 'Process: ' + str(self.get_object()),
            'opts': opts,
            'app_label': opts.app_label,
            'has_chage_permission': has_perm,
        })

        return context

文件 process_object.html:

{% extends "admin/change_form.html" %}
{% load i18n utils_tags %}

{% block content %}
...

2
使用 admin_site.each_context(self.request) (文档) 可能会给你提供更全面的上下文。 - BigglesZX
这是一个相当复杂但非常详细 - 因此令人鼓舞!- 的答案。谢谢。 - Olivier Pons

2

as_view() 方法是基于类的视图,返回常规视图,所以您可以像这样从 ModelAdmin 中调用:

def review(self, request, id):
    return MyReviewView.as_view()(request, id)

as_view() takes 1 positional argument but 2 were given - Cerin

2
您可以直接传递基于类的视图的`as_view`,而无需像另一个答案建议的那样拥有一个名为`awesome_book_view` 的变量:
例如:
在`admin.py`中,我有:
class EmailAdmin(admin.ModelAdmin):

    def get_urls(self):
        urls = super(EmailAdmin, self).get_urls()
        my_urls = [
            url(r'^send_email/$',
                self.admin_site.admin_view(SendEmailAdminView.as_view())),
        ]
        return my_urls + urls

admin.site.register(Email, EmailAdmin)

views.py中我有:

class SendEmailAdminView(View):

    def get(self, request):
        pass

    def post(self, request):
        pass

为了简洁起见,我已删除大部分代码,只保留相关部分。您可以在此处查看完整代码


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接