У меня есть следующие модели (упрощенный пример):
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, потому что это считается только тогда, когда активным является True. Я пытался написать собственный метод очистки (например, как я сделал здесь ). Но кажется, что когда вы сохраняете книгу и она запускает проверку для каждого разрешения, уже проверенные экземпляры разрешения не сохраняются, пока все они не будут проверены. Это имеет смысл, потому что вы не хотите, чтобы они были сохранены на случай, если что-то не подтвердится.
Может кто-нибудь сказать мне, если есть способ выполнить проверку, описанную выше?
P.S. Я мог бы представить себе использование функции сохранения (http://docs.djangoproject.com/en/1.2/topics/db/transactions/),, но я действительно хочу рассматривать это как последнее средство.
Может быть, вы можете сделать что-то вроде: unique_together = [[book, role, active=1],]
?
Редактировать 23 сентября 2010 г. 14:00 Ответ Маноджу Говиндану:
Мой 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. Таким образом, в оболочке, если вы добавляете 2 экземпляра Разрешения, 1-й экземпляр Разрешения был сохранен к моменту, когда 2-й будет проверено, и поэтому проверка работает.
Однако, когда вы используете интерфейс администратора и одновременно добавляете все экземпляры book.users через встроенных пользователей книги, я считаю, что он сначала выполняет всю проверку всех экземпляров book.users, а затем сохраняет их.
Когда я попробовал это сделать, проверка не сработала, просто она прошла успешно без ошибки, когда должна была быть ошибка ValidationError.