- February 1, 2010
- 0 (after 0 ratings)
When you have a model containing a field that is a foreign key back to the same model, you could find yourself with a hierarchy with an infinite loop:
Data modelling Back to the Future
grandfather > father > son > father > ...
Using this field instead of the standard ForeignKey will ensure that no model instance is saved that has itself as an ancestor, breaking the relationship if it does.
(Enhancements: I am sure one would want to better enhance this with appropriate error handling instead of silently disconnecting the relationship. And the relevant forms ought not show ancestors in the field's widget to reduce the chances of this happening in the first place.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
class SelfForeignKey(models.ForeignKey): def pre_save(self, instance, add): manager = instance.__class__.objects ancestor_id = getattr(instance, self.attname) while ancestor_id is not None: if ancestor_id == instance.id: return None ancestor = manager.get(id=ancestor_id) ancestor_id = getattr(ancestor, self.attname) return getattr(instance, self.attname) # used like this: class Category(models.Model): name = models.CharField(max_length=20) parent = SelfForeignKey('self', related_name='child_category_set', ...)
More like this
- Add custom fields to the built-in Group model by jmoppel 1 month, 1 week ago
- Month / Year SelectDateWidget based on django SelectDateWidget by pierreben 4 months, 3 weeks ago
- Python Django CRUD Example Tutorial by tuts_station 5 months, 1 week ago
- Browser-native date input field by kytta 6 months, 3 weeks ago
- Generate and render HTML Table by LLyaudet 7 months ago