Django-Admin:来自 UserProfile 的 list_filter 属性

2023-11-24

我希望允许我的网站管理员在管理网站上过滤来自特定国家/地区的用户。所以自然的做法是这样的:

#admin.py
class UserAdmin(django.contrib.auth.admin.UserAdmin):
    list_filter=('userprofile__country__name',)

#models.py
class UserProfile(models.Model)
    ...
    country=models.ForeignKey('Country')

class Country(models.Model)
    ...
    name=models.CharField(max_length=32)

但是,由于 django 中处理用户及其用户配置文件的方式,这会导致以下错误:

'UserAdmin.list_filter[0]' refers to field 'userprofile__country__name' that is missing from model 'User'

我如何绕过这个限制?


您正在寻找的是自定义管理过滤器规格。坏消息是,对那些可能不会很快发布的支持(您可以跟踪讨论here).

然而,您可以通过肮脏的黑客攻击来解决该限制。关于如何进行的一些要点FilterSpecs在深入代码之前构建:

  • 在构建列表时FilterSpec要在页面上显示,Django 使用您提供的字段列表list_filter
  • 这些字段需要real模型上的字段,不是反向关系,也不是自定义属性。
  • Django 维护着一个列表FilterSpec类,每个类与一个相关联test功能。
  • 对于每个字段list_filter, Django 将使用第一个FilterSpec类为test函数返回True对于该领域。

好的,现在考虑到这一点,看看下面的代码。它改编自一个 Django 片段。代码的组织由您自行决定,只需记住这应该由admin app.

from myapp.models import UserProfile, Country
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin

from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy as _

class ProfileCountryFilterSpec(ChoicesFilterSpec):
    def __init__(self, f, request, params, model, model_admin):
        ChoicesFilterSpec.__init__(self, f, request, params, model, model_admin)

        # The lookup string that will be added to the queryset
        # by this filter
        self.lookup_kwarg = 'userprofile__country__name'
        # get the current filter value from GET (we will use it to know
        # which filter item is selected)
        self.lookup_val = request.GET.get(self.lookup_kwarg)

        # Prepare the list of unique, country name, ordered alphabetically
        country_qs = Country.objects.distinct().order_by('name')
        self.lookup_choices = country_qs.values_list('name', flat=True)

    def choices(self, cl):
        # Generator that returns all the possible item in the filter
        # including an 'All' item.
        yield { 'selected': self.lookup_val is None,
                'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
                'display': _('All') }
        for val in self.lookup_choices:
            yield { 'selected' : smart_unicode(val) == self.lookup_val,
                    'query_string': cl.get_query_string({self.lookup_kwarg: val}),
                    'display': val }

    def title(self):
        # return the title displayed above your filter
        return _('user\'s country')

# Here, we insert the new FilterSpec at the first position, to be sure
# it gets picked up before any other
FilterSpec.filter_specs.insert(0,
  # If the field has a `profilecountry_filter` attribute set to True
  # the this FilterSpec will be used
  (lambda f: getattr(f, 'profilecountry_filter', False), ProfileCountryFilterSpec)
)


# Now, how to use this filter in UserAdmin,
# We have to use one of the field of User model and
# add a profilecountry_filter attribute to it.
# This field will then activate the country filter if we
# place it in `list_filter`, but we won't be able to use
# it in its own filter anymore.

User._meta.get_field('email').profilecountry_filter = True

class MyUserAdmin(UserAdmin):
  list_filter = ('email',) + UserAdmin.list_filter

# register the new UserAdmin
from django.contrib.admin import site
site.unregister(User)
site.register(User, MyUserAdmin)

显然这不是万能药,但它会完成这项工作,等待更好的解决方案出现。(例如,一个将子类化的解决方案)ChangeList并覆盖get_filters).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django-Admin:来自 UserProfile 的 list_filter 属性 的相关文章

随机推荐

  • 在 ajax 调用上显示 *浏览器* 加载指示器(例如发生回发时)

    示例 转到您的 Facebook 墙 滚动页面末尾 Facebook 将加载更多墙帖子异步地 或者只需单击墙上帖子中的图像 图像对话框 带有注释和较大图像 正在加载异步地以及 您可以使用 firebug 查看 GET 请求 但是通过查看 F
  • MVC 重定向到默认路由

    这是我的默认路线 routes MapRouteLowercase Default country controller action id new country uk controller Home action Index id Ur
  • 在 Ruby 中使用对象的属性对对象列表进行排序

    我有一个清单Fruit结构体称为basket Each Fruit结构体有一个name 一个字符串 和一个calories 一个整数 我想排序basket以便 The Fruits 最高的calories首先出现 例如 500 卡路里的水果
  • 互斥体和临界区有什么区别?

    请从Linux Windows角度解释一下 我正在用 C 编程 这两个术语有什么区别吗 请尽可能多地发帖 附上例子等等 Thanks 对于 Windows 临界区比互斥量更轻 互斥体可以在进程之间共享 但总是会导致对内核的系统调用 从而产生
  • 在 Swift 中访问 Flutter SharedPreferences

    是否可以访问SharedPreferences从 Flutter 中保存并在插件的 Swift 代码中访问 在Android中我们有FILE模式为SharedPreferences Swift 4 中有类似的功能吗 The shared p
  • nodejs websocket 检测断开的套接字

    我有一个nodejs websocket 服务器 但有以下问题 当我的客户端连接到服务器并正常终止时onclose在这些套接字上调用方法 然后对关闭的套接字执行清理操作 当客户端因网络原因断开连接时 onclose方法未被调用 是否有超时时
  • 外部 gem 的资产管道编码问题(UTF-8 与 ASCII-8BIT)

    我正在尝试创建一个包装 d3 js 的 gem 源代码可以在https github com iblue d3 rails 所以当我将这个 gem 包含在我的 Gemfile 中时 gem d3 rails git gt git githu
  • 如何检查表单是否打开,如果打开关闭表单?

    如何检查表单是否打开以及是否打开以关闭表单 我尝试了以下操作 测试了一些代码 但它一直说表单未打开 即使我知道它是 foreach Form a in Application OpenForms if a is YouLikeHits Se
  • 必须采用“app_label.ModelName”形式。" % model ValueError: 无效的模型引用

    When I python3 manage py makemigrations 我收到以下错误 File Library Frameworks Python framework Versions 3 5 lib python3 5 site
  • ASP.Net MVC:dbml 文件的最佳实践

    这可能只是一个是或否类型的问题 但无论如何 从我见过的使用 mvc 的所有 以及大多数 示例来看 创建 dbml 文件的方法似乎只是将数据库的整个架构放入其中 并让它自动生成所有 linq to sql 的优点 看来您只需要其中一个 因为您
  • 如何打开控制台与 Express 应用程序交互?

    如何打开控制台与我的 Express 应用程序交互 我正在尝试测试某些方法是否可以创建模型 我正在使用 SequelizeJS 但这对于这个问题的答案应该不重要 我已经习惯了 Rails 我可以做的事情 heroku run rails c
  • 无法删除 webpack 捆绑 js 文件中的注释

    我一直在尝试删除 webpack 捆绑的 js 文件中的注释 我已经尝试了几种方法 但它仍然不起作用 我收到这样的评论 n Copyright 2013 present Facebook Inc n All rights reserved
  • MessageDialog ShowAsync 在第二个对话框上引发 accessdenied 异常

    我正在尝试在 Windows 8 中实现重试 取消对话框 该对话框第一次显示正常 但单击重试并再次失败时 我在调用 ShowAsync 时遇到访问被拒绝的异常 我不知道为什么 但奇怪的是有时代码工作正常 当我设置断点时我没有得到异常 这里真
  • 使用 Code First 对 3 个表之间的多对多关系进行建模

    我有以下 3 个实体 User Account Role 关系就像 一个用户可以拥有多个帐户 一个账户可以属于多个用户 每个用户在帐户中都有一个角色 有一些预定义的角色 在枚举 Roles 中定义 我到目前为止 public class U
  • 在 Heroku 环境中 POST 请求被视为 GET

    我有一个奇怪的案例 我有一个 RoR 应用程序 它提供了我从 Java 应用程序连接到的 REST API 我正在本地开发 RoR 并将其部署在 Heroku 环境中 不管如何 我尝试从 Java APP Mozilla REST 客户端等
  • 在 Python 中浏览文件和子文件夹

    我想浏览当前文件夹及其所有子文件夹并获取所有带有 htm html 扩展名的文件 我发现可以像这样确定一个对象是目录还是文件 import os dirList os listdir current directory for dir in
  • 如何在sql server中实现多列全文搜索?

    我正在尝试对我为其创建视图的两列实施全文搜索 VendorName ProductName 我有全文索引等工作 但实际查询是导致我出现一些问题的原因 我希望用户能够使用一些标准搜索约定 AND OR NOT 以及按 进行术语分组 这很好 但
  • 如何将具有相同类型项目的列表列表合并到单个项目列表?

    这个问题很混乱 但是通过下面的代码描述就清楚多了 List
  • 迭代器与 for

    在一次采访中有人问我使用迭代器比使用迭代器有什么优势for循环或使用有什么好处for循环迭代器 有谁可以回答这个问题吗 首先 for 循环有两种 它们的行为非常不同 一种使用索引 for int i 0 i lt list size i T
  • Django-Admin:来自 UserProfile 的 list_filter 属性

    我希望允许我的网站管理员在管理网站上过滤来自特定国家 地区的用户 所以自然的做法是这样的 admin py class UserAdmin django contrib auth admin UserAdmin list filter us