使用内联formset和Model表单在Admin中进行表单验证

时间:2022-10-16 15:53:00

I have a model, OrderedList, which is intended to be a listing of content objects ordered by the user. The OrderedList has several attributes, including a site which it belongs to.

我有一个模型OrderedList,它是用户订购的内容对象的列表。 OrderedList有几个属性,包括它所属的站点。

The content objects are attached to it via an OrderedListRow class, which is brought into OrderedList's admin via an inline formset in the admin.

内容对象通过OrderedListRow类附加到它上面,该类通过admin中的内联formset引入OrderedList的管理员。

class OrderedList(GenericList):

    objects = models.Manager()
    published = GenericListManager()

class OrderedListRow(models.Model):

    list = models.ForeignKey(OrderedList)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveSmallIntegerField()
    content_object = generic.GenericForeignKey("content_type", "object_id")
    order = models.IntegerField('order', blank = True, null = True)

(OrderedList inherits the site field from the larger GenericList abstract).

(OrderedList从较大的GenericList摘要继承站点字段)。

Here's my problem; when the user saves the admin form, I want to verify that each content object mapped to by each OrderedListRow belongs to the same site that the OrderedList does (the list can only belong to 1 site; the content objects can belong to multiple).

这是我的问题;当用户保存管理表单时,我想验证每个OrderedListRow映射到的每个内容对象是否属于OrderedList所执行的同一站点(该列表只能属于1个站点;内容对象可以属于多个)。

I can override OrderedList's admin form's clean(), but it doesn't include the inline formset which contains the OrderedListRows, so it can't reach that data. I can override the OrderedListRows' inline formset's clean, but it can't reach the list. I need some way within the context of form validation to reach both the OrderedList's form data and the formset's form data so I can check all the sites of the OrderedListRow's content objects against the site of the OrderedList, and throw a validation error if there's a problem. So far I haven't found a function that the cleaned data for both OrderedRow and the OrderedListRows are contained in.

我可以覆盖OrderedList的管理表单的clean(),但它不包含包含OrderedListRows的内联formset,因此它无法访问该数据。我可以覆盖OrderedListRows的内联formset的干净,但它无法到达列表。我需要在表单验证的上下文中使用某种方式来访问OrderedList的表单数据和表单集的表单数据,这样我就可以针对OrderedList的站点检查OrderedListRow的内容对象的所有站点,如果出现问题则抛出验证错误。到目前为止,我还没有找到包含OrderedRow和OrderedListRows的清理数据的函数。

2 个解决方案

#1


5  

In the inline formset, self.instance should refer to the parent object, ie the OrderedList.

在内联formset中,self.instance应该引用父对象,即OrderedList。

#2


1  

I am dealing with the same issue. And unfortunately I don't think the answer above covers things entirely.

我正在处理同样的问题。不幸的是,我不认为上面的答案完全涵盖了一些事情。

If there are changes in both the inline formset and the admin form, accessing self.instance will not give accurate data, since you will base the validation on the database and then save the formset which overwrites that data you just used to validate things. Basically this makes your validation one save behind.

如果内联表单集和管理表单都有变化,访问self.instance将无法提供准确的数据,因为您将验证基于数据库,然后保存表单集,该表单集将覆盖您刚刚用于验证事物的数据。基本上这会使你的验证豁免。

I suppose the real question here is which gets saved first. After digging int he source code, it seems like the admin site saved the form first. This means that, logically, doing validation on the formset and from there accessing the 'parent' instance should get consistent values.

我想这里真正的问题是首先得到保存。在挖掘源代码之后,似乎管理站点首先保存了表单。这意味着,从逻辑上讲,对formset进行验证并从那里访问“父”实例应获得一致的值。

#1


5  

In the inline formset, self.instance should refer to the parent object, ie the OrderedList.

在内联formset中,self.instance应该引用父对象,即OrderedList。

#2


1  

I am dealing with the same issue. And unfortunately I don't think the answer above covers things entirely.

我正在处理同样的问题。不幸的是,我不认为上面的答案完全涵盖了一些事情。

If there are changes in both the inline formset and the admin form, accessing self.instance will not give accurate data, since you will base the validation on the database and then save the formset which overwrites that data you just used to validate things. Basically this makes your validation one save behind.

如果内联表单集和管理表单都有变化,访问self.instance将无法提供准确的数据,因为您将验证基于数据库,然后保存表单集,该表单集将覆盖您刚刚用于验证事物的数据。基本上这会使你的验证豁免。

I suppose the real question here is which gets saved first. After digging int he source code, it seems like the admin site saved the form first. This means that, logically, doing validation on the formset and from there accessing the 'parent' instance should get consistent values.

我想这里真正的问题是首先得到保存。在挖掘源代码之后,似乎管理站点首先保存了表单。这意味着,从逻辑上讲,对formset进行验证并从那里访问“父”实例应获得一致的值。