【问题标题】:Django - How to get admin url from model instanceDjango - 如何从模型实例中获取管理员 URL
【发布时间】:2012-05-12 07:29:50
【问题描述】:

我正在尝试在保存新模型实例时向用户发送电子邮件,并且我希望电子邮件包含指向该模型实例管理页面的链接。有没有办法获得正确的网址?我认为 Django 必须将这些信息存储在某个地方。

【问题讨论】:

    标签: python django django-models django-admin


    【解决方案1】:

    这个Django snippet 应该这样做:

    from django.urls import reverse
    from django.contrib.contenttypes.models import ContentType
    from django.db import models
    
    class MyModel(models.Model):
    
        def get_admin_url(self):
            content_type = ContentType.objects.get_for_model(self.__class__)
            return reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,))
    

    self 指的是父模型类,即self.id 指的是对象的实例id。您还可以通过将@property 装饰器粘贴在方法签名的顶部,将其设置为模型上的property

    编辑: Chris Pratt below 的答案在 ContentType 表上保存了一个数据库查询。我的回答仍然“有效”,并且较少依赖于 Django 模型instance._meta 内部。仅供参考。

    【讨论】:

    • 这些答案似乎不起作用。我刚回来“/admin/tracker/order/2/”。如何获取主机名?
    • @Greg 当然,上面的get_admin_url() 为您提供了主机名之后的部分。使用 Django sites 框架来适当地获取当前站点的主机名。然后将其添加到get_admin_url() 的结果前面。
    • 在 1.8 中也可以正常工作
    【解决方案2】:

    只需使用这个也支持 python 3 的衬垫:

    from django.urls import reverse
    
    reverse('admin:{0}_{1}_change'.format(self._meta.app_label, self._meta.model_name), args=(self.pk,))
    

    更多信息请参见 django 管理站点文档reversing admin urls

    【讨论】:

    • 应该是self._meta.model_name 而不是self._meta.module_name
    • 感谢@nedned,修复
    • 只是因为有可能:reverse('admin:{m.app_label}_{m.model_name}_change'.format(m=self._meta), args=[self.pk])
    【解决方案3】:

    这给出了与 Josvic Zammit 的 sn-p 相同的结果,但没有命中数据库:

    from django.urls import reverse
    from django.db import models
    
    class MyModel(models.Model):
    
        def get_admin_url(self):
            return reverse("admin:%s_%s_change" % (self._meta.app_label, self._meta.model_name), args=(self.id,))
    

    【讨论】:

    • 将 attr module_name 更改为 model_namemodule_name 未定义)
    • Django 1.8 将模型元对象中的“module_name”属性重命名为“model_name”。代码 sn-p 更新...谢谢!
    • 如果我有多个 AdminSite 实例怎么办?如何获取当前而不是admin:
    • @EugZol,我会为每个管理员分配一个名称,然后在 reverse() 中使用它。例如,在 urlspatterns 中: path('admin_ex/', admin_ex.urls, name="admin_ex");然后反向('admin_ex:label_model_action')。然而,从来没有需要在实践中使用它。
    • @MarioOrlandi 谢谢!
    【解决方案4】:

    不要试图扯掉@JosvicZammit,而是使用ContentType 是错误的做法。这只是一个浪费的数据库查询。您可以从_meta 属性中获取需求信息:

    from django.urls import reverse
    
    info = (model_instance._meta.app_label, model_instance._meta.model_name)
    admin_url = reverse('admin:%s_%s_change' % info, args=(model_instance.pk,))
    

    【讨论】:

    • 如果你能有效地在 cmets 中做代码示例,我会想要的。这将是一个绝对的混乱。我注意到 Josvic 给出了答案,他也因此得到了赞誉,所以,没有冒犯,但真的不知道为什么你应该在事实发生将近一年后才关心。
    【解决方案5】:

    因此,结合 Chris、Josvic 和 Josh 的答案,您可以将这里的复制粘贴方法添加到您的模型中(在 Django 1.8.3 上测试)。

    def get_admin_url(self):
        """the url to the Django admin interface for the model instance"""
        from django.core.urlresolvers import reverse
        info = (self._meta.app_label, self._meta.model_name)
        return reverse('admin:%s_%s_change' % info, args=(self.pk,))
    

    【讨论】:

      猜你喜欢
      • 2015-11-15
      • 2013-04-20
      • 2014-04-23
      • 1970-01-01
      • 2017-06-08
      • 2021-12-11
      • 2011-01-23
      • 1970-01-01
      • 2013-02-03
      相关资源
      最近更新 更多