First implementation of new Tags and LiteAttribute models to replace Aliases and Nicks while offering more flexibility.

This commit is contained in:
Griatch 2013-07-12 11:12:21 +02:00
parent e2ce3f2223
commit e178963941
2 changed files with 233 additions and 7 deletions

View file

@ -5,7 +5,7 @@ all Attributes and TypedObjects).
"""
from functools import update_wrapper
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from src.utils import idmapper
from src.utils.utils import make_iter
from src.utils.dbserialize import to_pickle
@ -50,7 +50,7 @@ class AttributeManager(models.Manager):
def exists(self,*args, **kwargs):
return super(AttributeManager, self).exists(*args, **kwargs)
def attr_namesearch(self, searchstr, obj, exact_match=True):
def get_attrs_on_obj(self, searchstr, obj, exact_match=True):
"""
Searches the object's attributes for attribute key matches.
@ -63,7 +63,11 @@ class AttributeManager(models.Manager):
else:
return _GA("obj", "db_attributes").filter(db_key__icontains=searchstr)
def attr_valuesearch(self, searchstr, obj=None):
def attr_namesearch(self, *args, **kwargs):
"alias wrapper for backwards compatability"
return self.get_attrs_on_obj(*args, **kwargs)
def get_attr_by_value(self, searchstr, obj=None):
"""
Searches obj for Attributes with a given value.
searchstr - value to search for. This may be any suitable object.
@ -78,6 +82,128 @@ class AttributeManager(models.Manager):
return _GA(obj, "db_attributes").filter(db_value=searchstr)
return self.filter(db_value=searchstr)
def attr_valuesearch(self, *args, **kwargs):
"alias wrapper for backwards compatability"
return self.get_attr_by_value(self, *args, **kwargs)
#
# LiteAttributeManager
#
class LiteAttributeManager(models.Manager):
"""
Manager methods for LiteAttributes
"""
def get_lattrs_on_obj(self, obj, search_key=None, category=None):
"""
Get all lattrs on obj, optionally limited by key and/or category
"""
if search_key or category:
key_cands = Q(db_key__iexact=search_key.lower().strip()) if search_key!=None else Q()
cat_cands = Q(db_category__iexact=category.lower.strip()) if search_key!=None else Q()
return _GA(obj, "db_tags").filter(cat_cands & key_cands)
else:
return list(_GA(obj, "db_tags").all())
def get_lattr(self, search_key=None, category=None):
"""
Search and return all liteattrs matching any combination of
the search criteria.
search_key (string) - the lattr identifier
category (string) - the lattr category
"""
key_cands = Q(db_key__iexact=search_key.lower().strip()) if search_key!=None else Q()
cat_cands = Q(db_category__iexact=category.lower.strip()) if search_key!=None else Q()
return list(self.filter(key_cands & cat_cands))
def get_lattr_data(self, obj=None, search_key=None, category=None):
"""
Retrieve data from found lattrs in an efficient way. Returns a list of data
matching the search criterions
"""
key_cands = Q(db_key__iexact=search_key.lower().strip()) if search_key!=None else Q()
cat_cands = Q(db_category__iexact=category.lower.strip()) if search_key!=None else Q()
if obj:
query = _GA(obj, "db_liteattributes").filter(key_cands & cat_cands).prefetch_related("db_data")
else:
query = self.filter(key_cands & cat_cands).prefetch_related("db_data")
return [q.db_data for q in query]
def create_lattr(self, key, category=None, data=None, obj=None):
"""
Create a LiteAttribute. This makes sure the create case-insensitive keys.
"""
lattr = self.objects.create(db_key=key.lower().strip(),
db_category=category.lower().strip() if category!=None else None,
db_data=str(data) if data!=None else None)
lattr.save()
if obj:
obj.db_liteattributes.add(lattr)
return lattr
#
# TagManager
#
class TagManager(models.Manager):
"""
Extra manager methods for Tags
"""
def get_tags_on_obj(self, obj, search_key=None, category=None):
"""
Get all tags on obj, optionally limited by key and/or category
"""
if search_key or category:
key_cands = Q(db_key__iexact=search_key.lower().strip()) if search_key!=None else Q()
cat_cands = Q(db_category__iexact=category.lower.strip()) if search_key!=None else Q()
return _GA(obj, "db_tags").filter(cat_cands & key_cands)
else:
return list(_GA(obj, "db_tags").all())
def get_tag(self, search_key=None, category=None):
"""
Search and return all tags matching any combination of
the search criteria.
search_key (string) - the tag identifier
category (string) - the tag category
"""
key_cands = Q(db_key__iexact=search_key.lower().strip()) if search_key!=None else Q()
cat_cands = Q(db_category__iexact=category.lower.strip()) if search_key!=None else Q()
return list(self.filter(key_cands & cat_cands))
def get_objs_with_tag(self, objclass, search_key=None, category=None):
"""
Search and return all objects of objclass that has tags matching
the given search criteria.
objclass (dbmodel) - the object class to search
search_key (string) - the tag identifier
category (string) - the tag category
"""
key_cands = Q(db_tags__db_key__iexact=search_key.lower().strip()) if search_key!=None else Q()
cat_cands = Q(db_tags__db_category__iexact=category.lower().strip()) if category!=None else Q()
return objclass.objects.filter(key_cands & cat_cands)
def create_tag(self, key=None, category=None, data=None):
"""
Create a tag. This makes sure the create case-insensitive tags.
Note that if the exact same tag configuration (key+category)
exists, it will be re-used. A data keyword will overwrite existing
data on a tag (it is not part of what makes the tag unique).
"""
data = str(data) if data!=None else None
tag = self.get_tag(search_key=key, search_category=category)
if tag and data != None:
tag.db_data = data
tag.save()
elif not tag:
tag = self.objects.create(db_key=key.lower().strip() if key!=None else None,
db_category=category.lower().strip() if key!=None else None,
db_data=str(data) if data!=None else None)
tag.save()
return tag
#
# helper functions for the TypedObjectManager.