我有以下型號(簡化的例子):Django的:驗證一個多到許多通過模型
class Book(models.Model):
users = models.ManyToManyField(User, through=Permission)
class Permission(models.Model):
user = models.ForeignKey(User)
role = models.ForeignKey(Group)
active = models.BooleanField()
book = models.ForeignKey(Book)
我需要的是,對於一個Book實例不能有與多個用戶相同的角色和主動。 所以這是允許的:
Alice, Admin, False (not active), BookA
Dick, Admin, True (active), BookA
Chris, Editor, False (not active), BookA
Matt, Editor, False (not active), BookA
但是,這是不允許的:
Alice, Admin, True (active), BookA
Dick, Admin, True (active), BookA
現在,這不能與unique_together完成,因爲它只有當活動是真正重要的。我試圖寫一個自定義的清潔方法(就像我已經完成here)。但是,當您保存一本書並且它在每個Permission上運行驗證時,似乎已經驗證的Permission實例在所有驗證完成之後纔會保存。這是有道理的,因爲你不希望他們被保存以防萬一不能確認。
任何人都可以告訴我是否有辦法執行上述驗證?
P.S.我可以想象使用保存點功能(http://docs.djangoproject.com/en/1.2/topics/db/transactions/),但我只是真的想把它作爲最後的手段。
也許你可以做點像:unique_together = [[book, role, active=1],]
?
編輯2010年9月23日14:00迴應馬諾Govindan:
我的admin.py(簡本爲清楚起見):
class BookAdmin(admin.ModelAdmin):
inlines = (PermissionInline,)
class PermissionInline(admin.TabularInline):
model = Permission
在您的驗證工作將外殼。因爲您首先必須創建書本實例,然後逐個創建所有權限實例:http://docs.djangoproject.com/en/1.2/topics/db/models/#extra-fields-on-many-to-many-relationships。因此,在shell中,如果添加2個Permission實例,則第2個正在驗證的時間已經保存了第1個Permission實例,因此驗證工作。
但是,當您使用Admin界面並通過書籍用戶內聯同時添加所有book.users實例時,我相信它會先保存所有book.users實例上的所有驗證。 當我嘗試它時,驗證不起作用,它應該有一個ValidationError時沒有錯誤就成功了。
感謝您的回覆!不幸的是,它不起作用,因爲當你第一次創建實例時,'Permission.objects.filter(** options).count()'將總是返回0.你在Book Permission Inline中輸入的權限有尚未保存,因此它們不會在數據庫中,因此您無法使用'Permission.objects.filter'來捕獲它們。我測試過了,這確實是發生了什麼事。 – Heyl1 2010-09-23 10:13:39
@ Heyl1:恐怕我不明白。不應該第一次創建條目?否則,權限將如何創建? – 2010-09-23 10:19:39
書本實例和book.users實例在驗證之後纔會保存。這是有道理的,因爲如果驗證返回一個ValidationError,它們不應該被保存。 Permission.objects.filter將僅返回已保存的內容,因此永遠不會包含您現在創建的新Permission對象。因此,此驗證將始終返回OK(除非更新實例,否則它將檢查舊版book.users,它可能在此更新版本中發生了更改,所以現在驗證只是不正確)。 – Heyl1 2010-09-23 11:31:17