django - 如何交叉检查 ModelAdmin 及其内联?

2023-11-23

我有两个模型(ModelParent 和 ModelChild),在主题模型上具有相同的 m2m 字段。 ModelChild 在 ModelParent 上有一个外键,并且 ModelChild 在管理页面上被定义为 ModelParent 的内联。

### models.py ###
  class Subject(Models.Model):
    pass

  class ModelParent(models.Model):
    subjects_parent = ManyToManyField(Subject)

  class ModelChild(models.Model):
    parent = ForeignKey(ModelParent)
    subjects_child = ManyToManyField(Subject)

### admin.py ###
  class ModelChildInline(admin.TabularInline):
      model = ModelChild

  class ModelParentAdmin(admin.ModelAdmin):
    inlines = [ModelChildInline]

  admin.site.register(ModelParent, ModelParentAdmin)

不过,我有一个重要的限制,ModelChild 的subjects_child 字段不得引用subject_parent 与其subjects_parent 所做的任何主题。

因此,如果我在两个模型的管理页面上选择相同的主题(在 subject_parent 和 subject_child 中),我该如何验证这一点? 如果只有一个字段发生变化,您可以根据数据库对其进行验证,但如果两者都发生变化(subject_parent 和 subject_child)怎么办? 如何在保存之前同时验证这两个表单?


我从 admin.ModelAdmin 继承了一个名为 ModelAdminWithInline 的新类,并修改了方法 add_view(...) 和 change_view(...) 来调用函数 is_cross_valid(self, form, formsets) ,您可以在其中一起验证所有表单。 这两个功能都有:

#...
if all_valid(formsets) and form_validated:
#...

变成:

#...
formsets_validated = all_valid(formsets)
cross_validated = self.is_cross_valid(form, formsets)
if formsets_validated and form_validated and cross_validated:
#...

新函数 is_cross_valid(...) 定义如下:

def is_cross_valid(self, form, formsets):
  return True

因此,如果您不更改 is_cross_valid(...) 函数,新类应该与 ModelAdmin 完全相同。

现在我的 admin.py 看起来像这样:

###admin.py###
class ModelAdminWithInline(admin.ModelAdmin):
  def is_cross_valid(self, form, formsets):
    return True

  def add_view(self, request, form_url='', extra_context=None):
    #modified code

  def change_view(self, request, object_id, extra_context=None):
    #modified code

class ModelChildInline(admin.TabularInline):
  model = ModelChild

class ModelParentAdmin(ModelAdminWithInline):
  inlines = [ModelChildInline]

  def is_cross_valid(self, form, formsets):
    #Do some cross validation on forms
    #For example, here is my particular validation:
    valid = True

    if hasattr(form, 'cleaned_data'):   

      subjects_parent = form.cleaned_data.get("subjects_parent")

      #You can access forms from formsets like this:
      for formset in formsets:
        for formset_form in formset.forms:
          if hasattr(formset_form, 'cleaned_data'):

            subjects_child = formset_form.cleaned_data.get("subjects_child")
            delete_form = formset_form.cleaned_data.get("DELETE")

            if subjects_child and (delete_form == False):
              for subject in subjects_child:
                if subject in subjects_parent:
                  valid = False
                  #From here you can still report errors like in regular forms:
                  if "subjects_child" in formset_form.cleaned_data.keys():
                    formset_form._errors["subjects_child"] = ErrorList([u"Subject %s is already selected in parent ModelParent" % subject])
                    del formset_form.cleaned_data["subjects_child"]
                  else:
                    formset_form._errors["subjects_child"] += ErrorList(u"Subject %s is already selected in parent ModelParent" % subject])

      #return True on success or False otherwise.
      return valid

admin.site.register(ModelParent, ModelParentAdmin)

该解决方案有点hackish,但它有效:)。这些错误的显示与常规 ModelForm 和 ModelAdmin 类相同。 Django 1.2(应该很快就会发布)应该有模型验证,所以我希望这个问题能够得到更好的解决。

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

django - 如何交叉检查 ModelAdmin 及其内联? 的相关文章

随机推荐

  • 在android中从图库和相机捕获图像

    我首先知道这是一个重复的问题 但我在从画廊或相机捕获图像方面没有问题 我在虚拟项目上创建来检查我的代码 它工作正常 但是当我在我的项目中使用相同的代码时 即使我没有收到任何错误 它也不起作用 一旦我开始活动以获取结果 它就会被取消 但我仍然
  • 如何修复 1 字节 UTF-8 序列的无效字节 1

    我正在尝试使用 java 方法从数据库获取以下 xml 但出现错误 用于解析xml的代码 DocumentBuilderFactory dbf DocumentBuilderFactory newInstance DocumentBuild
  • 我什么时候应该使用一对一关系?

    抱歉这个菜鸟问题 但是是否确实需要与数据库中的表使用一对一关系 您可以在一张表中实现所有必需的字段 即使数据变得非常大 您也可以枚举您需要的列名SELECT声明而不是使用SELECT 你什么时候真正需要这种分离 1 到 0 1 超类和子类之
  • 如何创建模块化 JSF 2.0 应用程序?

    我有一个具有明确定义的界面的应用程序 它使用 CDI 来解析模块 具体来说 它使用 API 接口上的 Instance 注入点来解析模块 并通过接口毫无问题地来回传递各种数据 我故意将 API 和实现分开 模块仅从 API 继承以避免紧密耦
  • 从 Delphi REST 服务器返回图像并在浏览器中显示它

    当您在 Delphi Rest 服务器中使用文件流对象返回图像时 它将不会在浏览器中显示 以下是返回图像的示例方法 function TServerClass Image TFileStream begin Result TFileStre
  • java.lang.RuntimeException:Parcel android.os.Parcel:解组未知类型代码

    我的应用程序中似乎出现了一个奇怪的错误 请参阅GitHub 当我将对象传递给实现的不同活动时 就会发生这种情况Parcelable 我在 Stack Overflow 上检查了其他问题和答案 但无法找到解决方案 我已经尝试过答案here 例
  • List 内的 NavigationLink 适用于 HStack 而不是每个元素

    我正在努力追随组合复杂的接口SwiftUI 指南 但在让 NavigationLink 在 iOS 13 beta 3 和现在的 beta 4 上正常工作时遇到问题 如果您只是下载项目文件并尝试运行它 请单击任何 Lake 图像 什么都不会
  • 是否可以在 ASP.NET MVC 路径中的查询字符串变量到达控制器之前更改它?

    我在 ASP NET MVC 中有一个控制器方法 如下所示 public ActionResult GetAlbumPictures int albumId var album AlbumRepo GetSingle albumId var
  • 执行 exe 时出现未知发布者错误

    我已经部署了我的 Windows 应用程序项目 但是当我运行它时 它首先抛出错误 未知发布者 如何隐藏此消息 您必须对包进行数字签名以防止此类错误 http msdn microsoft com library ms172240 aspx
  • Java - 执行 I/O 操作时的线程状态

    假设 Java 线程执行一些 I O 操作 例如使用传统的阻塞 Java I O 读取文件 问题是 等待时线程的状态是什么 我不知道它是正在运行 进行一些主动等待 还是正在等待 也许有某种监视器在文件数据准备好时唤醒线程 我怎样才能找到它
  • 可以在 php 5.2.6 中使用 SplEnum 吗?

    我尝试使用类 abstract class my abstractEnum extends SplEnum and class my categoryEnum extends my abstractEnum 我有 致命错误 未找到 SplE
  • 需要 Gradle 版本 2.2。当前版本是2.10

    我正在尝试使用 gradle 构建 它给了我错误的说法 无法应用插件 id com android library 需要 Gradle 版本 2 2 当前版本是2 10 如果使用 gradle 包装器 请尝试将 home sanjeewa
  • 致命错误:超出最大执行时间 300 秒

    我不断收到此 PHP 错误 致命错误 超出最大执行时间 300 秒 我尝试过设置我的max execution time and my max input timephp ini apache 和 cli 中的设置0 1 and 4000每
  • 模式匹配“返回”值

    为什么不可能链接模式匹配结构 例如 以下内容是合法的 如果是无意义的 val a ADT 5 val b a match case ADT a if a gt 4 gt ADT a 3 case ADT a gt ADT a 1 b mat
  • MySQL 事务与会计应用程序

    我有一个如下表 transaction id user id other user id trans type amount 该表用于维护金融类型应用程序的帐户交易 它采用复式记账法 因此从用户 A 到 B 的转账将在表中插入两行 如下所示
  • 地理坐标到街道名称

    是任何方式 与restAPI会很棒 来获取与地理坐标对应的街道名称 我认为这个名字是geocoding google有这个API吗 我是 PHP 开发人员 Ex 因此该函数的输出是街道名称 邮政编码和城市 感谢您提供任何帮助和脚本示例 是的
  • 函数侦听器无法启动。 Azure函数应用程序时间触发

    当我在本地环境中从 Visual Studio 运行 azure 函数时 出现以下错误 函数 Function1 的侦听器无法启动 Microsoft WindowsAzure Storage 错误请求 这是我的代码 using Syste
  • Vim - 如何使您自己的映射可重复?

    我的 vimrc 中有以下映射 nmap
  • 将自定义上下文菜单项添加到 Windows 窗体标题栏

    I found a threadMSDN 上展示了如何将项目添加到 Windows 窗体标题栏的上下文菜单 不幸的是 它没有显示如何使用自定义菜单项注册事件 我一直无法弄清楚如何做到这一点 下面是一个示例应用程序 可以将其复制并粘贴到新的
  • django - 如何交叉检查 ModelAdmin 及其内联?

    我有两个模型 ModelParent 和 ModelChild 在主题模型上具有相同的 m2m 字段 ModelChild 在 ModelParent 上有一个外键 并且 ModelChild 在管理页面上被定义为 ModelParent