开发者

Validation on ManyToManyField before Save in Models.py

开发者 https://www.devze.com 2023-01-03 10:45 出处:网络
I have the following models: class Application(models.Model): users = models.ManyToManyField(User, through=\'Permission\')

I have the following models:

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)

What I would like to do is to check whether one of the users of the Application has the same company as the Application (via Folder). If this is the case the Application instance should not be saved.

The problem is that the ManyToManyFields aren't updated until after the 'post-save' signal.

The only option seems to be the new m2m_changed signal. But I'm not sure how I then roll back the save that has already happened.

Another option would be to rewrite t开发者_JAVA百科he save function (in models.py, because I'm talking about the admin here), but I'm not sure how I could access the manytomanyfield content.

Finally I've read something about rewriting the save function in the admin of the model in admin.py, however I still wouldn't know how you would access the manytomanyfield content.

I have been searching for this everywhere but nothing I come across seems to work for me.

If anything is unclear, please tell me.

Thanks for your help!

Heleen


Because I didn't get a reply from Botondus I decided to ask a new question in the Django Users Google Group and finally got the answer from jaymz.

I figured that Botondus method was the right way of doing it, it just wasn't quite working. The reason that it doesn't work in this case is because I'm using a Through model for the field I would like to do the validation on. Because of some earlier feedback I got on a previously posted question I gathered that first the Application instance is saved and then the ManyToMany instances are saved (I believe this is right, but correct me if I'm wrong). So I thought that, if I would perform the validation on the ManyToMany Field in the Through model, this would not prevent the Application instance being saved. But in fact it does prevent that from happening.

So if you have a ManyToMany Field inline in your model's admin and you would like to do validation on that field, you specify the clean function in the through model, like this:

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 

If the validation results in an error NOTHING (neither the application instance, nor the manytomany users instances) is saved and you get the chance to correct the error.


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

Edit: Replaced initial (wrong) model validation example with form validation.

0

精彩评论

暂无评论...
验证码 换一张
取 消