在 Django 管理中设置内联条件
我有一个模型,希望工作人员能够在活动日期之前对其进行编辑。像这样:
class ThingAdmin(admin.ModelAdmin):
model = Thing
if obj.date < today: #Something like that
inlines = [MyInline,]
问题是,我无权访问此级别的 obj 实例。我尝试过重写 get_formset(),但没有成功。
请指教?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
感谢 1.4 中更改的评论。我这里的实现也不是线程安全的,所以它确实应该被删除。
由于
get_formsets
传递了对象并调用get_inline_instances
,因此我们可以修改这两个函数以作用于对象。这应该有效:
Thanks to the comments for a change in 1.4. My implementation here wasn't thread safe either, so it really should have been deleted.
Since
get_formsets
is passed the object and callsget_inline_instances
, we can modify both functions to act on the object.This should work:
从 Django 2.2.2(撰写本文时的最新版本)开始,我将使用 @aggieNick02 之前提供的解决方案,即覆盖下面所示的
get_inline_instances
。我发布这个新答案是因为截至 2019 年 4 月 17 日 this提交,看来未来推荐的方法是重写
get_inlines
方法。因此,在更高版本中,此问题的解决方案可能类似于下面的代码,它允许您指定不同的内联集并根据条件使用它们。As of Django 2.2.2 (current latest version as of this writing), I would use the solution provided earlier by @aggieNick02, which is to override
get_inline_instances
shown below.I'm posting this new answer because as of April 17th, 2019 in this commit, it looks like the future recommended way to do this would be to instead override the
get_inlines
method. So in later versions, the solution to this could look like the code below, which allows you to specify different sets of inlines and use them based on a condition.您可以使用(django 3.0+)get_inlines 方法。您所要做的就是重写该方法并定义您的逻辑,
更新:
通过这种方法,我遇到了 这个问题 因此,可以通过覆盖
change_view()
方法,You can use (django 3.0+) get_inlines method. All you have to do is override the method and define your logic,
Update:
Going through this approach I faced this issue so instead of using the above mentioned approach samething can be done by overidding
change_view()
method,我遇到了一个复杂的情况,我尝试的解决方案以意想不到的方式失败(内联只读字段的问题)。这是我发现的最清晰、最安全的方法:
这在 Django 1.4.x 中有效。
I had a complex case where the solutions I tried failed in unexpected ways (problems with readonly fields in inlines). This is the most clear and failsafe way I've found:
This is working in Django 1.4.x.
在最新版本的 Django 中,您需要重写 ModelAdmin.get_formsets。例如
In recent version of Django, you'll need to override ModelAdmin.get_formsets. e.g.
此问题的最佳解决方案已在此处得到解答。而不是覆盖
get_inline_instances
覆盖change_view
方法。The best solution for this issue is already answered here. Instead of overriding
get_inline_instances
overridechange_view
method.我遇到过一种情况,我需要根据您所在的给定故事的管理网站显示内嵌内容。
我能够使用以下代码获得适用于 Django 1.3 的动态内联:
Inhighlights/admin.py
Instory/admin.py
需要注意的一件事是我'我不仅仅是操作内联类(HighlightInline),而是更改内联实例(HighlightInline(self.model,self.admin_site))。这是因为django在管理类的初始构建过程中已经根据内联类列表构建了内联实例列表。
I had a situation where I needed to show an Inline based on the admin site that you were on for a given story.
I was able to get dynamic inlines working for Django 1.3 using the following code:
In highlights/admin.py
In story/admin.py
One thing to note is that I'm not merely manipulating inline classes(HighlightInline) but rather, I'm changing inline instances(HighlightInline(self.model, self.admin_site)). This is because django has already constructed a list of inline instances based on a list of inline classes during the initial construction of the admin class.
我认为解决这个问题的最简单方法是在
get_fields
,或get_fieldsets
等,只需在自定义函数中设置self.inlines
即可。I think the easiest way to hack this is to call your custom funciton in
get_fields
, orget_fieldsets
and so on, just setself.inlines
in a custom function.现在最完整的方法是覆盖并超级调用 get_inline_instances。
这会在您需要时将 MyInline 放入,而在您不需要时则不放入。如果您知道类中唯一的内联是 MyInline,则可以使其变得更简单:
The most turnkey way to do this now is to override and super call to get_inline_instances.
This puts MyInline in when you want it and not when you don't. If you know the only inline you have in your class is MyInline, you can make it even simpler: