Проверка на ManyToManyField перед сохранением в Models.py - PullRequest
1 голос
/ 16 июня 2010

У меня есть следующие модели:

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)

Что я хотел бы сделать, это проверить, имеет ли один из пользователей Приложения ту же компанию, что и Приложение (через Папку). В этом случае экземпляр приложения не должен быть сохранен.

Проблема в том, что ManyToManyFields не обновляются до тех пор, пока не появится сигнал «после сохранения».
Единственным вариантом, по-видимому, является новый сигнал m2m_changed. Но я не уверен, как мне откатить сохранение, которое уже произошло.
Другой вариант - переписать функцию сохранения (в models.py, потому что я говорю об администраторе здесь), но я не уверен, как мне получить доступ к содержимому поля manytomany.
Наконец, я прочитал кое-что о переписывании функции сохранения в админке модели в admin.py, однако я все еще не знаю, как вы получите доступ к контенту manytomanyfield.

Я искал это везде, но ничего, с чем я сталкивался, похоже, не работает для меня.
Если что-то неясно, скажите, пожалуйста.

Спасибо за вашу помощь!
Heleen

Ответы [ 2 ]

1 голос
/ 16 июля 2010

Поскольку я не получил ответа от Botondus, я решил задать новый вопрос в Django Users Google Group и, наконец, получил ответ от jaymz.

Я понял, что Botondusметод был правильным способом сделать это, он просто не совсем работал.Причина, по которой это не работает в этом случае, заключается в том, что я использую модель Сквозного поля для поля, на котором я хотел бы выполнить проверку.Из-за некоторых предыдущих отзывов, которые я получил по ранее опубликованному вопросу, я понял, что сначала сохраняется экземпляр Application, а затем - экземпляры ManyToMany (я считаю, что это правильно, но поправьте меня, если я ошибаюсь).Поэтому я подумал, что, если я выполню проверку поля ManyToMany в сквозной модели, это не помешает сохранению экземпляра приложения.Но на самом деле это предотвращает это.

Таким образом, если у вас есть встроенное поле ManyToMany в администраторе вашей модели и вы хотите выполнить проверку этого поля, вы задаете чистую функцию в сквозной модели, например:

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 

Если проверка приводит к ошибке, НИЧЕГО (ни экземпляр приложения, ни множество пользователей) не сохраняется, и вы получаете возможность исправить ошибку.

0 голосов
/ 16 июня 2010

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

Редактировать : заменена начальная (неправильно) пример проверки модели с проверкой формы.

...