I'm thinking on the best way to set a relationship with django's built-in User
or Group
.
By 'or' I mean that the model instances must be exclusively owned by an User
or by a Group
.
I think the question should be easy to understand by having a look at my model above.
This is my current implementation. I've been looking at GenericRelations but they don't seen appropiate when restricted to such a small number of models.
EDIT: Refactor with an abstract model.
class OwnedModel(models.Model):
_owner_user = models.ForeignKey(User, null=True, related_name='%(class)s')
_owner_group = models.ForeignKey(Group, null=True, related_name='%(class)s')
class Meta:
abstract = True
@property
def owner(self):
return self._owner_user or self._owner_group
@owner.setter
def owner(self, value):
if isinstance(value, User):
self._owner_user = value
if self._owner_group:
self._owner_group = None
elif isinstance(value, Group):
self._owner_group = value
if self._owner_user:
self._owner_user = None
else:
raise ValueError
class RemoteAccess(OwnedModel):
SSH = 's'
SUPPORTED_PROTOCOLS = (
(SSH, "ssh"),
)
host = models.CharField(_('host name'), max_length=255, validators=[full_domain_validator])
protocol = models.CharField(_('protocol'), max_length=1, choices=SUPPORTED_PROTOCOLS, default=SSH)
credential = models.OneToOneField(RemoteCredential)
My main issues with my current implementation are:
User
or Group
when creating the instance?
Could an __init__
override be the way to go?Thanks!
I would override the save() method instead and define a custom exception
def save(self, *args, **kwargs):
if self._owner_user is None and self._owner_group is None:
raise NoOwner
super(OwnedModel, self).save(*args, **kwargs)
Overriding the init might cause problems in certain cases where you don't actually have the owner until the save (such as in forms etc.)
I don't think there is a cleaner way to do this and stick with the Django User/Group.