views:

31

answers:

2

Hallo Folks,

I hope you can help me with a little problem I came in touch with while building a model with a foreign key to itself.

Here an example:

class Example (model.Model):
    parent = models.ForeignKey('self', null=True, blank=True)
    # and some other fields

After creating a new entry in the admin panel and going into this example for editing some content, I realize that I could set the parent to the current entry. But thats not what I wanted to get with the ForeignKey and the relation to itself.

Is it possible to disallow the link to itself?

Maybe it's better to use a integer field with the right choices but I'm not quiet sure how to realize this an a smooth and Python like way.

Big thanks
Lemmi

+1  A: 

one way to do this would be to override the model's clean method

class Example(model.Model):
    #...
    def clean(self):
        if self.parent.id == self.id:
            raise ValidationError("no self referential models")

this will be called as the second step of object validation and will prevent the object from being inserted in the database.

aaronasterling
Yes, that's the way to go. It is explained in the Model Validation section of the doc: http://docs.djangoproject.com/en/1.2/ref/models/instances/#validating-objects
Barthelemy
Thats a bit awesome! :) Thank you for this.
Lemmi
Another question to this topic: Is it possible to assign this error to a specific field? And in addition to this to disable the option from the select in the admin panel? The typical cosmetic surgery. ;)
Lemmi
@Lemmi assuming that this is for the admin, I would use [this technique](http://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin)
aaronasterling
@AaronMcSmooth Thank you! I already know why signed in here.
Lemmi
For everyone looking for a solution deleting the choice for self refercing in the ForeignKey ... http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_foreignkey
Lemmi
A: 

It is possible to disallow a link from an instance to the same instance. One way to achieve this would be to add a custom model validation. For e.g.

class Example(models.Model):
    ...
    def clean_fields(self):
        if self.id and self.parent.id == self.id:
            raise ValidationError(...)
Manoj Govindan