【问题标题】:Change model object url in django admin list using template overriding使用模板覆盖更改 django 管理列表中的模型对象 url
【发布时间】:2020-02-14 01:25:41
【问题描述】:

假设我有一个 Category 的模型,并且它已经在 admin.py 中声明了。

我想使用 Django 模板覆盖来做两件事。

  • 在右侧“添加类别+”附近添加一个按钮,该按钮仅在“类别列表”页面上可见,并将我带到另一个 URL。
  • 覆盖 Category 对象的 URL,以便单击列表中的每个单独的类别会转到相应的 URL
# models.py

class Category(models.Model):
    name = models.CharField(max_length=50, null=True, blank=False)
    LANGUAGE_ENGLISH = 'en'
    LANGUAGE_FRENCH = 'fr'

    LANGUAGES = ((LANGUAGE_ENGLISH, 'English'),(LANGUAGE_FRENCH, 'French'),)

    language = models.CharField(max_length=12, default=LANGUAGE_ENGLISH, choices=LANGUAGES, blank=False)
    created_at = models.DateTimeField(auto_now_add=True)
# admin.py

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('name', 'language', 'created_at')
    list_filter = ('created_at', 'language')
    search_fields = ('name',)
    date_hierarchy = 'created_at'
    ordering = ['-created_at']

管理面板中的类别 在这里,点击 Lifestyle 或 Travel 应该会将我带到两个外部 URL。

【问题讨论】:

    标签: python django django-templates


    【解决方案1】:

    第一个解决方案:

    覆盖 list_display_links 并手动更改您的字段

    这是一个两步过程。 首先,我们需要改变get_list_display_links的默认行为。

    查看 django 的 docsource 你会发现它最终会使用 list_display 中的第一项。 在您的管理员课程中:

    @admin.register(Category)
    class CategoryAdmin(admin.ModelAdmin):
        list_display = ('name', 'language', 'created_at')
        list_filter = ('created_at', 'language')
        list_display_links = [] #< With this, you still can add up a link to your original admin
        search_fields = ('name',)
        date_hierarchy = 'created_at'
        ordering = ['-created_at']
    
        def get_list_display_links(self, request, list_display):
            """
            Return a sequence containing the fields to be displayed as links
            on the changelist. The list_display parameter is the list of fields
            returned by get_list_display().
            """
            if self.list_display_links or self.list_display_links is None or not list_display:
                # We make sure you still add your admin's links if you explicitly declare `list_display_links`
                return self.list_display_links 
            else:
                # We return empty list instead of `list_display[:1]`
                # if no `list_display_links` is provided.
                return []
    

    然后使用this answer,您可以自定义任何列。

    第二种解决方案:

    自己处理更改视图

    在您的管理员课程中:

    @admin.register(Category)
    class CategoryAdmin(admin.ModelAdmin):
       #... same things as you have
    
       def change_view(self, request, object_id, form_url="", extra_context=None):
           #Now, you can do pretty much whatever: it's a function based view!
    

    我推荐第一个,因为我相信默认管理员的change_view 总是有用的。

    【讨论】:

    • 它对我不起作用。我添加了list_display_links = [] 定义的get_list_display_links 行,就像上面显示的一样。然后,根据name(self,obj)定义的第二个答案返回html元素。你认为我做错了什么?
    • 不考虑name(self,obj) 部分:您有仅使用list_display_links 的链接吗?
    • 请改写。
    • 忘记html 标记。当我只添加list_display_links = []get_list_display_links 时,第一列的原始链接不再存在。你这边还好吗?
    • 您建议的代码运行良好,是可接受的解决方案。需要为第 2 步添加一个新的字段名称。如果可以更改现有字段的链接,那就太好了。另外,你能麻烦把 get_list_display_links() 弄得一头雾水吗?理解起来会有很大帮助。
    猜你喜欢
    • 2013-01-23
    • 2011-08-06
    • 2020-11-16
    • 2019-05-02
    • 2011-07-26
    • 1970-01-01
    • 2018-02-01
    • 2018-10-22
    • 2011-06-15
    相关资源
    最近更新 更多