我有以下型号:
class Application(models.Model):
users = models.ManyToManyField(User, through='Permission')
folder = models.ForeignKey(Folder)
class Folder(models.Model):
company = models.ManyToManyField(Compnay)
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
company = models.ManyToManyField(Company)
我想做的是检查应用程序的某个用户是否与应用程序(通过文件夹)具有相同的公司。如果是这种情况,则不应保存Application实例。
问题是,在“保存后”信号之后,ManyToManyFields才会更新。
唯一的选择似乎是新的m2m_changed信号。但是我不确定我如何回滚已经发生的豁免
另一个选择是重写保存功能(在models.py中,因为我在这里谈论管理员),但我不确定如何访问manytomanyfield内容。
最后,我已经阅读了一些关于在admin.py中重写模型管理员中的保存功能的内容,但是我仍然不知道如何访问manytomanyfield内容。
我一直在寻找这个,但我遇到的任何东西似乎对我都有用 如果有任何不清楚的地方,请告诉我。
感谢您的帮助!
Heleen
答案 0 :(得分:1)
因为我没有收到Botondus的回复,所以我决定在Django Users Google Group中提出一个新问题,最后得到了jaymz的答案。
我认为Botondus方法是正确的方法,它只是不太有用。它在这种情况下不起作用的原因是因为我在字段中使用了穿透模型,我想对其进行验证。由于我之前发布的一些问题得到了反馈,我首先收集了应用程序实例,然后保存了ManyToMany实例(我相信这是正确的,但如果我错了,请纠正我)。所以我想,如果我在Through模型中对ManyToMany字段执行验证,这不会阻止保存Application实例。但实际上它确实可以防止这种情况发生。
因此,如果您的模型管理员中有一个ManyToMany字段内联,并且您想对该字段进行验证,则在直通模型中指定clean函数,如下所示:
admin.py
class PermissionInline(admin.TabularInline):
form = PermissionForm
model = Permission
extra = 3
forms.py
class PermissionForm(forms.ModelForm):
class Meta:
model = Permission
def clean(self):
cleaned_data = self.cleaned_data
user = cleaned_data['user']
role = cleaned_data['role']
if role.id != 1:
folder = cleaned_data['application'].folder
if len(filter(lambda x:x in user.profile.company.all(),folder.company.all())) > 0: # this is an intersection
raise forms.ValidationError("One of the users of this Application works for one of the Repository's organisations!")
return cleaned_data
如果验证导致错误NOTHING(既没有应用程序实例也没有多个用户实例),那么您就有机会纠正错误。
答案 1 :(得分:0)
<强> forms.py 强>
class ApplicationForm(ModelForm):
class Meta:
model = Application
def clean(self):
cleaned_data = self.cleaned_data
users = cleaned_data['users']
folder = cleaned_data['folder']
if users.filter(profile__company__in=folder.company.all()).count() > 0:
raise forms.ValidationError('One of the users of this Application works in one of the Folder companies!')
return cleaned_data
<强> admin.py 强>
class ApplicationAdmin(ModelAdmin):
form = ApplicationForm
修改:用表单验证替换了初始(错误)模型验证示例。