- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在 Django 1.5.1 中,我设置了一个供内部使用的 SAAS 系统,每个部门都在其中获取自己的数据集。
为此,我使用 ModelAdmin.queryset ( https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#django.contrib.admin.ModelAdmin.queryset ) 将所有数据限制为仅属于当前登录用户所在部门的记录.
这非常适合主要的管理功能(汇总表等)。但是我放在 "ModelAdmin.list_filter" 上的任何内容都会显示所有值 - 显然使用的是基本查询集,而不是我在 ModelAdmin.queryset 中定义的那个。
我可以在这里看到如何定义自定义 ModelAdmin.list_filter 查询:https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter这让您还可以定义一个自定义过滤器管理器,其中可以包含一个自定义查询集。
但这是PER FILTER FIELD!
对于添加 ModelAdmin.queryset 后应该自动执行的操作来说,这似乎是一项非常繁重的工作!
有没有我在这里缺少的更简单的方法,或者这是我应该出票的方法?
提前致谢
丰富。
Peter,谢谢你踢我的裤子。原来我对自己问题的理解是错误的!
================= 来 self 的代码的示例 ================
class Company(models.Model):
"""Company model."""
accountid = models.CharField(_('Account Number'), max_length=20, null=False, blank=True, help_text="Link to old system and records")
name = models.CharField(_('name'), max_length=200, unique=True, help_text=_("Enter full company name, no abbreviations. Duplicates are not allowed."))
nickname = models.CharField(_('nickname'), max_length=50, blank=True, null=True, help_text=_("Enter one or more keywords or abbreviations seperated by a space to make searching easier"))
slug = AutoSlugField(_('slug'), max_length=50, unique=True, blank=False, populate_from=('name', ))
site = models.ForeignKey(Site, default="0", blank=False, null=False, editable=False, help_text="Indicate which site this record belongs to. ")
class CompanyAdmin(admin.ModelAdmin):
list_filter = ('type', 'lead_quality', )
def queryset(self, request):
qs = super(PersonAdmin, self).queryset(request)
if request.user.is_superuser:
self.message_user(request, "Warning: This is the ADMINISTRATOR view!!", 'warning')
return qs
return qs.filter(site__id=request.session['site'].id)
def save_model(self, request, obj, form, change):
if change:
if obj.site.id != request.session['site'].id:
logger.debug("Contacts.Person.save_model: replacing site (%s) with (%s) " % (repr(obj.site), repr(request.session['site'])) )
else:
logger.debug("Contacts.Person.save_model: setting site (%s)" % (repr(request.session['site'])) )
obj.site = request.session['site']
obj.save()
class Person(models.Model):
"""Person model."""
first_name = models.CharField(_('first name'), max_length=100)
last_name = models.CharField(_('last name'), max_length=200)
slug = AutoSlugField(_('slug'), max_length=50, unique=True, blank=False, populate_from=('first_name', 'last_name'))
company = models.ForeignKey(Company, blank=True, null=True, help_text=_("If this person is associated with a Company, indicate which one here.") )
site = models.ForeignKey(Site, default="0", blank=False, null=False, editable=False, help_text="Indicate which site this record belongs to. ")
class PersonAdmin(admin.ModelAdmin):
list_filter = ('company',)
def queryset(self, request):
qs = super(PersonAdmin, self).queryset(request)
if request.user.is_superuser:
self.message_user(request, "Warning: This is the ADMINISTRATOR view!!", 'warning')
return qs
return qs.filter(site__id=request.session['site'].id)
def save_model(self, request, obj, form, change):
if change:
if obj.site.id != request.session['site'].id:
logger.debug("Contacts.Person.save_model: replacing site (%s) with (%s) " % (repr(obj.site), repr(request.session['site'])) )
else:
logger.debug("Contacts.Person.save_model: setting site (%s)" % (repr(request.session['site'])) )
obj.site = request.session['site']
obj.save()
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name in ('company',):
kwargs["queryset"] = Company.objects.get_query_set().filter(site__id=request.session['site'].id)
return super(PersonAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
因此,当用户查看People 的摘要屏幕并点击Company 的过滤器时,他们会看到属于其他公司部门的选项。
如果他们点击属于另一个部门的记录,他们会得到一个空列表,因为 PersonAdmin 实际上无法访问该记录。
最佳答案
您是否有任何特殊原因希望 list_filter
中的相关字段关心管理类上的查询集?此类过滤器通常不会删除不存在相关对象的值。
如果您不想要这种行为,您可以编写一个单独的过滤器类来限制选择,但是您喜欢作为 django.contrib.admin.filter.RelatedFieldListFilter
的子集并使用它,要么覆盖其 choices
方法(您在模型管理中定义的查询集将在该方法中作为 cl.root_query_set
提供)或覆盖其 __init__
方法以不同方式创建 self.lookup_choices
- 可能基于请求。我认为您没有理由必须继续重新定义类 - 一个定义应该适用于您喜欢的尽可能多的相关领域。
这是一个简单的查询,如果管理员的过滤查询集至少有一个对象作为过滤值,则应该只在过滤器中包含项目:
class RelatedFieldRestrictedListFilter(RelatedFieldListFilter):
def choices(self, cl):
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
yield {
'selected': self.lookup_val is None and not self.lookup_val_isnull,
'query_string': cl.get_query_string({},
[self.lookup_kwarg, self.lookup_kwarg_isnull]),
'display': _('All'),
}
for pk_val, val in self.lookup_choices:
if cl.root_query_set.filter(**{self.lookup_kwarg: pk_val}).exists():
yield {
'selected': self.lookup_val == smart_unicode(pk_val),
'query_string': cl.get_query_string({
self.lookup_kwarg: pk_val,
}, [self.lookup_kwarg_isnull]),
'display': val,
}
if (isinstance(self.field, models.related.RelatedObject)
and self.field.field.null or hasattr(self.field, 'rel')
and self.field.null):
yield {
'selected': bool(self.lookup_val_isnull),
'query_string': cl.get_query_string({
self.lookup_kwarg_isnull: 'True',
}, [self.lookup_kwarg]),
'display': EMPTY_CHANGELIST_VALUE,
}
这会针对 list_filter
字段中的每个可能值对数据库进行单独查询,因此效率有点低 - 如果这变成一个问题,您应该自定义 __init__
相反。
跟进:好的,所以正确的过滤器选择取决于请求 session 。这意味着您需要在子类的 __init__
方法中建立它们。您的示例显示了一个相关字段,因此我将再次使用 RelatedFieldListFilter
- 老实说,我不确定受限查询集的概念对任何其他类型的过滤器是否有意义。为此,惰性方法(编写更短、效率更低)是调用父类(super class)的 __init__
,然后更改 self.lookup_choices
。不太懒惰的方法是完全覆盖 __init__
。
惰性方法是这样的:
from django.utils.encoding import smart_unicode
class RelatedFieldRestrictedListFilter(RelatedFieldListFilter):
def __init__(self, field, request, params, model, model_admin, field_path):
super(RelatedFieldRestrictedListFilter, self).__init__(field, request, params, model, model_admin, field_path)
if 'site' in request.session:
self.lookup_choices = [(instance.pk, smart_unicode(instance) for instance in model.objects.filter(site=request.session['site'])]
else:
# something else here
不太懒惰的方法涉及从父类(super class)的 __init__
方法复制基本代码,并将 self.lookup_choices = field.get_choices(include_blank=False)
行替换为以上。
请注意,我考虑到 session 可能没有站点
的可能性 - 如果是这种情况,您应该考虑您希望发生什么。如果用户是 super 用户,也许不必费心更改 lookup_choices
。
关于python - Django 难以将 ModelAdmin.queryset 与 ModelAdmin.list_filter 一起使用来限制显示的过滤器 itrems,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20106425/
在 Django 1.5.1 中,我设置了一个供内部使用的 SAAS 系统,每个部门都在其中获取自己的数据集。 为此,我使用 ModelAdmin.queryset ( https://docs.dj
在 Django 中,您可以向表单添加一个 clean 方法来验证相互依赖的字段: def clean_recipients(self): data = self.cleaned_data['
有没有办法让 ModelAdmin 过滤器更持久?目前,如果您过滤、编辑 DataObject 并返回,过滤器就消失了。同样来自 unclecheese/betterbuttons 的 prev/ne
有没有办法扩展另一个应用程序 ModelAdmin? 我有一个使用 django.contrib.comments 提供的功能的项目。 CommentsAdmin ModelAdmin 类具有:act
我想让ModelAdmin界面显示为默认界面而不是Pages-有没有办法做到这一点? 最佳答案 您可以通过添加以下config.yml文件来设置默认管理面板: AdminRootController:
我想知道是否可以在 ModelAdmin 中以干净的方式打印外键链: 图像我们有这样的结构: class Ma(models.Model): fa = models.EmailField(
我正在从事 SilverStripe 项目。在我的项目中,我正在构建一个模型管理类来显示 CMS 中的记录列表。我试图限制每页呈现的记录数。所以我像这样将 $page_length 字段放在我的模型管
在 Silverstripe 3 中使用 ModelAdmin 管理 Dataobject 时,我想知道如何将自定义操作的按钮添加到 ListView 和编辑页面. 通过在 ModelAdmin 的
嘿,我对 Django 相当陌生,我希望动态编辑管理类变量(完整的想法是在添加时隐藏内联并仅在编辑时显示,但我在这里提炼了这个问题)。 有人可以解释为什么这不起作用吗? class dbTablePe
我有一个 ModelAdmin,我需要在其中插入一些不属于模型的 html 片段(它是一个 java 小程序)。有没有办法做到这一点? 最佳答案 你有几个选择。如果小程序与表单字段之一相关,那么您可以
并非所有软件都需要左侧的“内容制作者”管理界面和右侧的“访问者/成员”站点。 人们常说“管理员不是您的应用程序”(参见示例 the accepted answer (March 2009))。 我在
假设我有两个模型,位于不同的应用程序中。应用程序 2 知道应用程序 1,但应用程序 1 不知道应用程序 2: # one/models.py from django.db import models
我正在使用 SilverStripe4 和 ModelAdmin 来管理数据对象。 DataObject 在 File 上有一个 has_one。到目前为止一切正常,但在前端 Controller 上
我正在尝试通过模型中的 onetonefield 扩展 django 用户身份验证。这是模型: from django.db import models from django.contrib.aut
我在 model.Admin 中定义了自定义操作。 class ProjectAdmin(admin.ModelAdmin): list_display = ['ID','Name']
我是 Django 新手。我有以下代码: 型号: class MyUser(AbstractUser): profile = models.OneToOneField(Profile, nul
我正在尝试向我拥有的模型的 admin.ModelAdmin 添加额外的输入,以便在另一个输入发生更改时可以记录一些可选文本。 我无法将自定义ModelForm识别为名称“EquipmentAdmin
我在网上商店应用程序中有一个订单模型,它有一个自动递增的主键和一个指向自身的外键,因为订单可以拆分为多个订单,但必须保持与原始订单的关系。 class Order(models.Model):
最终,我的目标是扩展 Django 的 ModelAdmin 以提供字段级权限——也就是说,给定请求对象的属性和正在编辑的对象的字段值,我想控制字段/内联对用户可见。我最终通过向 ModelAdmin
我像这样在我的 Django 管理页面中添加了一个过滤器下拉列表。 class MyAdmin(admin.ModelAdmin): list_filter = ('status',) 默认情
我是一名优秀的程序员,十分优秀!