Created
March 26, 2013 13:41
-
-
Save FZambia/5245441 to your computer and use it in GitHub Desktop.
django relation between user and object using contenttypes framework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
from django.contrib.contenttypes.models import ContentType | |
from django.contrib.contenttypes import generic | |
class RelationManager(models.Manager): | |
""" | |
Contains helpful methods for operating with Relation model | |
""" | |
def __init__(self, *args, **kwargs): | |
self.default_relation_type = kwargs.pop('default_relation_type') | |
super(RelationManager, self).__init__(*args, **kwargs) | |
def _generate_kwarg_dict(self, content_object, user, relation_type): | |
""" | |
Create kwargs to use in manager methods. | |
""" | |
if relation_type is None: | |
relation_type = self.default_relation_type | |
if isinstance(content_object, models.Model): | |
ctype = ContentType.objects.get_for_model(content_object) | |
object_id = getattr( | |
content_object, | |
'pk', | |
getattr(content_object, 'id') | |
) | |
elif isinstance(content_object, dict): | |
content_type_id = content_object['content_type_id'] | |
object_id = content_object['object_id'] | |
ctype = ContentType.objects.get_for_id(content_type_id) | |
else: | |
raise Exception('malformed content_object type') | |
kwargs = { | |
'content_type': ctype, | |
'object_id': object_id, | |
'type': relation_type | |
} | |
if user: | |
if isinstance(user, list): | |
kwargs['user__in'] = user | |
else: | |
kwargs['user'] = user | |
return kwargs | |
def get_for_object(self, content_object, relation_type=None): | |
""" | |
Find all existing relations for content object. | |
""" | |
params = self._generate_kwarg_dict(content_object, None, relation_type) | |
return self.filter(**params).select_related('user', 'content_type') | |
def get_for_user_list(self, content_object, user_list, relation_type=None): | |
""" | |
Find all existing relations of certain relation type for list of users. | |
""" | |
params = self._generate_kwarg_dict(content_object, user_list, relation_type) | |
return self.filter(**params).select_related('user', 'content_type') | |
def get_for_user(self, content_object, user, relation_type=None): | |
""" | |
Find relation between content_object and user. | |
Return it if exists. Otherwise return None. | |
""" | |
params = self._generate_kwarg_dict(content_object, user, relation_type) | |
try: | |
item = self.get(**params) | |
except Relation.DoesNotExist: | |
return None | |
return item | |
def add_for_user(self, content_object, user, relation_type=None): | |
""" | |
Create relation between content_object and user if not exists yet. | |
""" | |
params = self._generate_kwarg_dict(content_object, user, relation_type) | |
obj, created = self.get_or_create(**params) | |
return obj | |
def del_for_user(self, content_object, user, relation_type=None): | |
""" | |
Delete relation between content_object and user. | |
""" | |
params = self._generate_kwarg_dict(content_object, user, relation_type) | |
return self.filter(**params).delete() | |
class Relation(models.Model): | |
""" | |
Generic relation between user and content object | |
""" | |
NOTIFICATIONS = 0 | |
TYPE_CHOICES = ( | |
(NOTIFICATIONS, u'общие уведомления об изменениях объекта'), | |
) | |
content_type = models.ForeignKey(ContentType) | |
object_id = models.PositiveIntegerField() | |
content_object = generic.GenericForeignKey('content_type', 'object_id') | |
user = models.ForeignKey(User, verbose_name=u"пользователь") | |
type = models.SmallIntegerField(u"тип связи", choices=TYPE_CHOICES, default=NOTIFICATIONS) | |
created_at = models.DateTimeField(u"создано", auto_now_add=True) | |
updated_at = models.DateTimeField(u"обновлено", auto_now=True) | |
objects = RelationManager(default_relation_type=NOTIFICATIONS) | |
def __unicode__(self): | |
return u"relation between user {0} and {1}:{2}".format( | |
self.user.username, | |
self.content_type.name, | |
self.object_id | |
) | |
class Meta: | |
verbose_name = "relation" | |
verbose_name_plural = "relations" | |
unique_together = ('content_type', 'object_id', 'user', 'type') | |
ordering = ('created_at',) | |
get_latest_by = 'id' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment