簡體   English   中英

如何為 django 管理員創建自定義頁面?

[英]How can I create custom page for django admin?

我想為沒有 model 的管理面板創建自定義頁面。首先我將 index.html 復制到項目文件夾:

mysite/
    templates/
        admin/
            index.html

然后添加到應用程序阻止我的代碼:

<div class="module">
    <table summary="{% blocktrans with name="preferences" %}Models available in the preferences application.{% endblocktrans %}">
        <caption><a href="preferences" class="section">{% blocktrans with name="preferences" %}Preferences{% endblocktrans %}</a></caption>
            <tr>
                <th scope="row"><a href="preferences">Preferences</a></th>
                <td><a href="preferences" class="changelink">{% trans 'Change' %}</a></td>
            </tr>
    </table>
</div>

這很好用,然后我創建新頁面 /templates/admin/preferences/preferences.html 並添加到 urls.py:

url(r'^admin/preferences/$', TemplateView.as_view(template_name='admin/preferences/preferences.html')),

並在 preferences.html 添加代碼:

{% extends "admin/base_site.html" %}
{% block title %}Test page{% endblock %}

運行它並看到錯誤消息“請求的管理頁面不存在。”。 我做錯了什么?

您需要在管理員本身的 URL 模式之前添加您的管理員 URL:

urlpatterns = patterns('',
   url(r'^admin/preferences/$', TemplateView.as_view(template_name='admin/preferences/preferences.html')),
   url(r'^admin/', include('django.contrib.admin.urls')),
)

這樣 URL 就不會被 Django 的管理員處理。

go 年,仍然可以發布對此的相關答案。

使用 Django 1.10+ 你可以這樣做:

security/admin.py(這是你應用程序的管理文件)

from django.contrib import admin
from django.conf.urls import url
from django.template.response import TemplateResponse
from security.models import Security


@admin.register(Security)
class SecurityAdmin(admin.ModelAdmin):

    def get_urls(self):

        # get the default urls
        urls = super(SecurityAdmin, self).get_urls()

        # define security urls
        security_urls = [
            url(r'^configuration/$', self.admin_site.admin_view(self.security_configuration))
            # Add here more urls if you want following same logic
        ]

        # Make sure here you place your added urls first than the admin default urls
        return security_urls + urls

    # Your view definition fn
    def security_configuration(self, request):
        context = dict(
            self.admin_site.each_context(request), # Include common variables for rendering the admin template.
            something="test",
        )
        return TemplateResponse(request, "configuration.html", context)

安全/模板/配置.html

{% extends "admin/base_site.html" %}
{% block content %}
...
{% endblock %}

請參閱官方 ModelAdmin.get_urls 說明(確保您的 select 正確 Django 版本,此代碼對 1.10 以上有效)

您應該使用管理員的get_urls

這是一個自定義管理頁面所需的一切示例(截至 Django 1.6),該頁面鏈接到對象詳細信息頁面右上角“歷史記錄”按鈕旁邊的按鈕:

https://gist.github.com/mattlong/4b64212e096766e058b7

完整示例:

from django.urls import path
from django.contrib import admin
from django.db import models

class DummyModel(models.Model):
    class Meta:
        verbose_name = 'Link to my shiny custom view'
        app_label = 'users'  # or another app to put your custom view

@admin.register(DummyModel)
class DummyModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        view_name = '{}_{}_changelist'.format(
                DummyModel._meta.app_label, DummyModel._meta.model_name)
        return [
            path('my_view/', MyCustomView.as_view(), name=view_name)
        ]

使用這種方法,Django 的makemigrations命令將創建數據庫遷移,為 DummyModel 創建表。

如果你想創建一個自定義頁面只是為了在那里放置一個任意表單來處理用戶輸入,你可以試試django-etc 您可以使用etc.admin.CustomModelPage

    # admin.py
    from etc.admin import CustomModelPage

    class MyPage(CustomModelPage):
    
        title = 'My custom page'  # set page title

        # Define some fields you want to proccess data from.
        my_field = models.CharField('some title', max_length=10)

        def save(self):
            # Here implement data handling.
            super().save()

    # Register the page within Django admin.
    MyPage.register()

根據django 的文檔,擴展AdminSite class 對我來說效果最好。 此解決方案在管理站點登錄機制下保護頁面,並且設置它比看起來更容易:

  1. 如果您有其他管理代碼(例如myapp/admin.py ),請擴展默認值 class:
from django.contrib.admin import AdminSite

class CustomAdminSite(AdminSite):

    def get_urls(self):
        custom_urls = [
            path('admin/preferences/', self.admin_view(views.my_view)),
        ]
        admin_urls = super().get_urls()
        return custom_urls + admin_urls  # custom urls must be at the beginning


site = CustomAdminSite()

# you can register your models on this site object as usual, if needed
site.register(Model, ModelAdmin)
  1. 實現視圖
def my_view(request):
    return render(request, 'admin/preferences/preferences.html')
  1. urls.py中使用該管理站點,而不是默認站點
from myapp import admin

# now use admin.site as you would use the default django one
urlpatterns = [
    # ...
    path('admin/', admin.site.urls),
    # ...
]

如果你想將一個頁面掛接到現有的管理站點,那么你可以執行以下操作,該操作基於上面#arnaud-p 的回答。 Arnaud 的回答對我不起作用,因為子類化 adminsite 的 get_url function 失去了對現有管理頁面的訪問權限,直到我按如下方式添加注冊表。 使用以下方法,您的其他頁面將需要員工訪問權限,並且您不需要更改 urls.py,因此這非常適合為應用程序等制作管理頁面......您可以在視圖中傳遞 each_context 以便獲得權限等適用於 django 3.2.9

在 admin.py 中

from django.contrib import admin
from django.urls import path

from . import views

class CustomAdminSite(admin.AdminSite):
    
    def get_urls(self):
        self._registry = admin.site._registry
        admin_urls = super().get_urls() 
        custom_urls = [
            path('preferences/', views.Preferences.as_view(admin=self), name="preferences"),
        ]
        return custom_urls + admin_urls # custom urls must be at the beginning

    def get(self):
        request.current_app == self.name
        return super().get(request)

    def get_app_list(self, request):
        app_list = super().get_app_list(request)
        app_list += [
            {
                "name": "My Custom Preferences App",
                "app_label": "Preferences",
                # "app_url": "/admin/test_view",
                "models": [
                    {
                        "name": "Preferences",
                        "object_name": "preferences",
                        "admin_url": "/admin/preferences",
                        "view_only": True,
                    }
                ],
            }
        ]
        return app_list

site = CustomAdminSite()

風景...

class Preferences(views.generic.ListView):
    admin = {}
    def get(self, request):
        ctx = self.admin.each_context(request)
        return render(request, 'admin/preferences/preferences.html', ctx)

模板...

{% extends "admin/base_site.html" %}
{% block content %}
...HELLO WORLD!
{% endblock %}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM