Removed LiteAttributes, made Nicks use Attributes. Added category and strvalue fields to Attribute. Made Attributes accessible through an AttributeHandler, like most other advanced properties.
This commit is contained in:
parent
befe6a6db0
commit
2f5c895f76
9 changed files with 609 additions and 420 deletions
|
|
@ -18,7 +18,7 @@ import traceback
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler
|
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler, AttributeHandler
|
||||||
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
||||||
from src.server.caches import get_prop_cache, set_prop_cache
|
from src.server.caches import get_prop_cache, set_prop_cache
|
||||||
|
|
||||||
|
|
@ -140,9 +140,10 @@ class ObjectDB(TypedObject):
|
||||||
_SA(self, "cmdset", CmdSetHandler(self))
|
_SA(self, "cmdset", CmdSetHandler(self))
|
||||||
_GA(self, "cmdset").update(init_mode=True)
|
_GA(self, "cmdset").update(init_mode=True)
|
||||||
_SA(self, "scripts", ScriptHandler(self))
|
_SA(self, "scripts", ScriptHandler(self))
|
||||||
_SA(self, "tags", TagHandler(self, category_prefix="object_"))
|
_SA(self, "attributes", AttributeHandler(self))
|
||||||
_SA(self, "aliases", AliasHandler(self, category_prefix="object_"))
|
_SA(self, "tags", TagHandler(self))
|
||||||
_SA(self, "nicks", NickHandler(self, category_prefix="object_"))
|
_SA(self, "aliases", AliasHandler(self))
|
||||||
|
_SA(self, "nicks", NickHandler(self))
|
||||||
# make sure to sync the contents cache when initializing
|
# make sure to sync the contents cache when initializing
|
||||||
self.contents_update()
|
self.contents_update()
|
||||||
|
|
||||||
|
|
@ -646,10 +647,10 @@ class ObjectDB(TypedObject):
|
||||||
raw_list = raw_string.split(None)
|
raw_list = raw_string.split(None)
|
||||||
raw_list = [" ".join(raw_list[:i+1]) for i in range(len(raw_list)) if raw_list[:i+1]]
|
raw_list = [" ".join(raw_list[:i+1]) for i in range(len(raw_list)) if raw_list[:i+1]]
|
||||||
# fetch the nick data efficiently
|
# fetch the nick data efficiently
|
||||||
nicks = self.db_liteattributes.filter(db_category__in=("object_nick_inputline", "object_nick_channel")).prefetch_related("db_key","db_data")
|
nicks = self.db_attributes.filter(db_category__in=("nick_inputline", "nick_channel")).prefetch_related("db_key","db_strvalue")
|
||||||
if self.has_player:
|
if self.has_player:
|
||||||
pnicks = self.player.db_liteattributes.filter(
|
pnicks = self.player.db_attributes.filter(
|
||||||
db_category__in=("player_nick_inputline", "player_nick_channel")).prefetch_related("db_key","db_data")
|
db_category__in=("nick_inputline", "nick_channel")).prefetch_related("db_key","db_strvalue")
|
||||||
nicks = list(nicks) + list(pnicks)
|
nicks = list(nicks) + list(pnicks)
|
||||||
for nick in nicks:
|
for nick in nicks:
|
||||||
if nick.db_key in raw_list:
|
if nick.db_key in raw_list:
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ from src.server.caches import get_field_cache, set_field_cache
|
||||||
|
|
||||||
from src.players import manager
|
from src.players import manager
|
||||||
from src.scripts.models import ScriptDB
|
from src.scripts.models import ScriptDB
|
||||||
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler
|
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler, AttributeHandler
|
||||||
from src.commands.cmdsethandler import CmdSetHandler
|
from src.commands.cmdsethandler import CmdSetHandler
|
||||||
from src.commands import cmdhandler
|
from src.commands import cmdhandler
|
||||||
from src.utils import utils
|
from src.utils import utils
|
||||||
|
|
@ -113,9 +113,10 @@ class PlayerDB(TypedObject, AbstractUser):
|
||||||
# handlers
|
# handlers
|
||||||
_SA(self, "cmdset", CmdSetHandler(self))
|
_SA(self, "cmdset", CmdSetHandler(self))
|
||||||
_GA(self, "cmdset").update(init_mode=True)
|
_GA(self, "cmdset").update(init_mode=True)
|
||||||
|
_SA(self, "attributes", AttributeHandler(self))
|
||||||
_SA(self, "tags", TagHandler(self, category_prefix="player_"))
|
_SA(self, "tags", TagHandler(self, category_prefix="player_"))
|
||||||
_SA(self, "aliases", AliasHandler(self, category_prefix="player_"))
|
_SA(self, "aliases", AliasHandler(self, category_prefix="player_"))
|
||||||
_SA(self, "nicks", NickHandler(self, category_prefix="player_"))
|
_SA(self, "nicks", NickHandler(self))
|
||||||
|
|
||||||
# Wrapper properties to easily set database fields. These are
|
# Wrapper properties to easily set database fields. These are
|
||||||
# @property decorators that allows to access these fields using
|
# @property decorators that allows to access these fields using
|
||||||
|
|
@ -483,8 +484,8 @@ class PlayerDB(TypedObject, AbstractUser):
|
||||||
raw_list = raw_string.split(None)
|
raw_list = raw_string.split(None)
|
||||||
raw_list = [" ".join(raw_list[:i+1]) for i in range(len(raw_list)) if raw_list[:i+1]]
|
raw_list = [" ".join(raw_list[:i+1]) for i in range(len(raw_list)) if raw_list[:i+1]]
|
||||||
# get the nick replacement data directly from the database to be able to use db_category__in
|
# get the nick replacement data directly from the database to be able to use db_category__in
|
||||||
nicks = self.db_liteattributes.filter(
|
nicks = self.db_attributes.filter(
|
||||||
db_category__in=("object_nick_inputline", "object_nick_channel")).prefetch_related("db_key","db_data")
|
db_category__in=("nick_inputline", "nick_channel")).prefetch_related("db_key","db_strvalue")
|
||||||
for nick in nicks:
|
for nick in nicks:
|
||||||
if nick.db_key in raw_list:
|
if nick.db_key in raw_list:
|
||||||
raw_string = raw_string.replace(nick.db_key, nick.db_data, 1)
|
raw_string = raw_string.replace(nick.db_key, nick.db_data, 1)
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.signals import post_init, pre_delete
|
from django.db.models.signals import post_init, pre_delete
|
||||||
|
|
||||||
from src.typeclasses.models import Attribute, TypedObject, TagHandler, AliasHandler, NickHandler
|
from src.typeclasses.models import Attribute, TypedObject, TagHandler, AttributeHandler#, AliasHandler, NickHandler
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from src.scripts.manager import ScriptManager
|
from src.scripts.manager import ScriptManager
|
||||||
|
|
||||||
|
|
@ -108,7 +108,8 @@ class ScriptDB(TypedObject):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(ScriptDB, self).__init__(*args, **kwargs)
|
super(ScriptDB, self).__init__(*args, **kwargs)
|
||||||
_SA(self, "tags", TagHandler(self, category_prefix="script_"))
|
_SA(self, "tags", TagHandler(self, category_prefix="script_"))
|
||||||
_SA(self, "aliases", AliasHandler(self, category_prefix="script_"))
|
_SA(self, "attributes", AttributeHandler(self))
|
||||||
|
#_SA(self, "aliases", AliasHandler(self, category_prefix="script_"))
|
||||||
|
|
||||||
# Wrapper properties to easily set database fields. These are
|
# Wrapper properties to easily set database fields. These are
|
||||||
# @property decorators that allows to access these fields using
|
# @property decorators that allows to access these fields using
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
|
||||||
for field in update_fields:
|
for field in update_fields:
|
||||||
fieldname = field.name
|
fieldname = field.name
|
||||||
new_value = field.value_from_object(instance)
|
new_value = field.value_from_object(instance)
|
||||||
|
# try to see if there is a handler on object that should be triggered when saving.
|
||||||
handlername = "_%s_handler" % fieldname
|
handlername = "_%s_handler" % fieldname
|
||||||
try:
|
try:
|
||||||
handler = _GA(instance, handlername)
|
handler = _GA(instance, handlername)
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class AttributeManager(models.Manager):
|
||||||
def exists(self,*args, **kwargs):
|
def exists(self,*args, **kwargs):
|
||||||
return super(AttributeManager, self).exists(*args, **kwargs)
|
return super(AttributeManager, self).exists(*args, **kwargs)
|
||||||
|
|
||||||
def get_attrs_on_obj(self, searchstr, obj, exact_match=True):
|
def get_attrs_on_obj(self, searchstr, obj, category=None, exact_match=True):
|
||||||
"""
|
"""
|
||||||
Searches the object's attributes for attribute key matches.
|
Searches the object's attributes for attribute key matches.
|
||||||
|
|
||||||
|
|
@ -58,10 +58,11 @@ class AttributeManager(models.Manager):
|
||||||
"""
|
"""
|
||||||
# Retrieve the list of attributes for this object.
|
# Retrieve the list of attributes for this object.
|
||||||
|
|
||||||
|
category_cond = Q(db_category__iexact=category) if category else Q()
|
||||||
if exact_match:
|
if exact_match:
|
||||||
return _GA("obj", "db_attributes").filter(db_key__iexact=searchstr)
|
return _GA("obj", "db_attributes").filter(db_key__iexact=searchstr & category_cond)
|
||||||
else:
|
else:
|
||||||
return _GA("obj", "db_attributes").filter(db_key__icontains=searchstr)
|
return _GA("obj", "db_attributes").filter(db_key__icontains=searchstr & category_cond)
|
||||||
|
|
||||||
def attr_namesearch(self, *args, **kwargs):
|
def attr_namesearch(self, *args, **kwargs):
|
||||||
"alias wrapper for backwards compatability"
|
"alias wrapper for backwards compatability"
|
||||||
|
|
@ -86,62 +87,6 @@ class AttributeManager(models.Manager):
|
||||||
"alias wrapper for backwards compatability"
|
"alias wrapper for backwards compatability"
|
||||||
return self.get_attr_by_value(self, *args, **kwargs)
|
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_liteattributes").filter(cat_cands & key_cands)
|
|
||||||
else:
|
|
||||||
return list(_GA(obj, "db_liteattributes").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
|
# TagManager
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
# Adding field 'Attribute.db_strvalue'
|
||||||
|
db.add_column(u'typeclasses_attribute', 'db_strvalue',
|
||||||
|
self.gf('django.db.models.fields.TextField')(null=True, blank=True),
|
||||||
|
keep_default=False)
|
||||||
|
|
||||||
|
# Adding field 'Attribute.db_category'
|
||||||
|
db.add_column(u'typeclasses_attribute', 'db_category',
|
||||||
|
self.gf('django.db.models.fields.CharField')(db_index=True, max_length=128, null=True, blank=True),
|
||||||
|
keep_default=False)
|
||||||
|
|
||||||
|
# Adding index on 'Tag', fields ['db_category']
|
||||||
|
db.create_index(u'typeclasses_tag', ['db_category'])
|
||||||
|
|
||||||
|
# Adding index on 'Tag', fields ['db_key']
|
||||||
|
db.create_index(u'typeclasses_tag', ['db_key'])
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Removing index on 'Tag', fields ['db_key']
|
||||||
|
db.delete_index(u'typeclasses_tag', ['db_key'])
|
||||||
|
|
||||||
|
# Removing index on 'Tag', fields ['db_category']
|
||||||
|
db.delete_index(u'typeclasses_tag', ['db_category'])
|
||||||
|
|
||||||
|
# Deleting field 'Attribute.db_strvalue'
|
||||||
|
db.delete_column(u'typeclasses_attribute', 'db_strvalue')
|
||||||
|
|
||||||
|
# Deleting field 'Attribute.db_category'
|
||||||
|
db.delete_column(u'typeclasses_attribute', 'db_category')
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
u'typeclasses.attribute': {
|
||||||
|
'Meta': {'object_name': 'Attribute'},
|
||||||
|
'db_category': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||||
|
'db_strvalue': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
u'typeclasses.liteattribute': {
|
||||||
|
'Meta': {'object_name': 'LiteAttribute', 'index_together': "(('db_key', 'db_category'),)"},
|
||||||
|
'db_category': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_data': ('django.db.models.fields.TextField', [], {}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
u'typeclasses.tag': {
|
||||||
|
'Meta': {'unique_together': "(('db_key', 'db_category'),)", 'object_name': 'Tag', 'index_together': "(('db_key', 'db_category'),)"},
|
||||||
|
'db_category': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'db_index': 'True'}),
|
||||||
|
'db_data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['typeclasses']
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
# Deleting model 'LiteAttribute'
|
||||||
|
db.delete_table(u'typeclasses_liteattribute')
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Adding index on 'LiteAttribute', fields ['db_key', 'db_category']
|
||||||
|
db.create_index(u'typeclasses_liteattribute', ['db_key', 'db_category'])
|
||||||
|
|
||||||
|
# Adding model 'LiteAttribute'
|
||||||
|
db.create_table(u'typeclasses_liteattribute', (
|
||||||
|
('db_category', self.gf('django.db.models.fields.CharField')(max_length=64, null=True, blank=True)),
|
||||||
|
('db_key', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||||
|
('db_data', self.gf('django.db.models.fields.TextField')()),
|
||||||
|
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||||
|
))
|
||||||
|
db.send_create_signal(u'typeclasses', ['LiteAttribute'])
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
u'typeclasses.attribute': {
|
||||||
|
'Meta': {'object_name': 'Attribute'},
|
||||||
|
'db_category': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||||
|
'db_strvalue': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_value': ('src.utils.picklefield.PickledObjectField', [], {'null': 'True'}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
u'typeclasses.tag': {
|
||||||
|
'Meta': {'unique_together': "(('db_key', 'db_category'),)", 'object_name': 'Tag', 'index_together': "(('db_key', 'db_category'),)"},
|
||||||
|
'db_category': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'db_index': 'True'}),
|
||||||
|
'db_data': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['typeclasses']
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -11,7 +11,7 @@ import os, threading
|
||||||
#from twisted.internet import reactor
|
#from twisted.internet import reactor
|
||||||
#from twisted.internet.threads import blockingCallFromThread
|
#from twisted.internet.threads import blockingCallFromThread
|
||||||
from twisted.internet.reactor import callFromThread
|
from twisted.internet.reactor import callFromThread
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist, FieldError
|
||||||
from django.db.models.base import Model, ModelBase
|
from django.db.models.base import Model, ModelBase
|
||||||
from django.db.models.signals import post_save, pre_delete, post_syncdb
|
from django.db.models.signals import post_save, pre_delete, post_syncdb
|
||||||
from src.utils.utils import dbref, get_evennia_pids
|
from src.utils.utils import dbref, get_evennia_pids
|
||||||
|
|
@ -83,7 +83,7 @@ class SharedMemoryModelBase(ModelBase):
|
||||||
document this auto-wrapping in the class header, this could seem very much like magic to the user otherwise.
|
document this auto-wrapping in the class header, this could seem very much like magic to the user otherwise.
|
||||||
"""
|
"""
|
||||||
super(SharedMemoryModelBase, cls).__init__(*args, **kwargs)
|
super(SharedMemoryModelBase, cls).__init__(*args, **kwargs)
|
||||||
def create_wrapper(cls, fieldname, wrappername):
|
def create_wrapper(cls, fieldname, wrappername, editable=True):
|
||||||
"Helper method to create property wrappers with unique names (must be in separate call)"
|
"Helper method to create property wrappers with unique names (must be in separate call)"
|
||||||
def _get(cls, fname):
|
def _get(cls, fname):
|
||||||
"Wrapper for getting database field"
|
"Wrapper for getting database field"
|
||||||
|
|
@ -94,6 +94,9 @@ class SharedMemoryModelBase(ModelBase):
|
||||||
return _GA(value, "typeclass")
|
return _GA(value, "typeclass")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def _set_nonedit(cls, fname, value):
|
||||||
|
"Wrapper for blocking editing of field"
|
||||||
|
raise FieldError("Field %s cannot be edited." % fname)
|
||||||
def _set(cls, fname, value):
|
def _set(cls, fname, value):
|
||||||
"Wrapper for setting database field"
|
"Wrapper for setting database field"
|
||||||
#print "_set:", fname
|
#print "_set:", fname
|
||||||
|
|
@ -108,7 +111,7 @@ class SharedMemoryModelBase(ModelBase):
|
||||||
try:
|
try:
|
||||||
value = cls._default_manager.get(id=dbid)
|
value = cls._default_manager.get(id=dbid)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
# maybe it is just a name
|
# maybe it is just a name that happens to look like a dbid
|
||||||
pass
|
pass
|
||||||
#print "_set wrapper:", fname, value, type(value), cls._get_pk_val(cls._meta)
|
#print "_set wrapper:", fname, value, type(value), cls._get_pk_val(cls._meta)
|
||||||
_SA(cls, fname, value)
|
_SA(cls, fname, value)
|
||||||
|
|
@ -117,6 +120,9 @@ class SharedMemoryModelBase(ModelBase):
|
||||||
update_fields = [fname] if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None else None
|
update_fields = [fname] if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None else None
|
||||||
_GA(cls, "save")(update_fields=update_fields)
|
_GA(cls, "save")(update_fields=update_fields)
|
||||||
|
|
||||||
|
def _del_nonedit(cls, fname):
|
||||||
|
"wrapper for not allowing deletion"
|
||||||
|
raise FieldError("Field %s cannot be edited." % fname)
|
||||||
def _del(cls, fname):
|
def _del(cls, fname):
|
||||||
"Wrapper for clearing database field - sets it to None"
|
"Wrapper for clearing database field - sets it to None"
|
||||||
_SA(cls, fname, None)
|
_SA(cls, fname, None)
|
||||||
|
|
@ -125,8 +131,8 @@ class SharedMemoryModelBase(ModelBase):
|
||||||
|
|
||||||
# create class wrappers
|
# create class wrappers
|
||||||
fget = lambda cls: _get(cls, fieldname)
|
fget = lambda cls: _get(cls, fieldname)
|
||||||
fset = lambda cls, val: _set(cls, fieldname, val)
|
fset = lambda cls, val: _set(cls, fieldname, val) if editable else _set_nonedit(cls, fieldname, val)
|
||||||
fdel = lambda cls: _del(cls, fieldname)
|
fdel = lambda cls: _del(cls, fieldname) if editable else _del_nonedit(cls,fieldname)
|
||||||
doc = "Wraps setting, saving and deleting the %s field." % fieldname
|
doc = "Wraps setting, saving and deleting the %s field." % fieldname
|
||||||
type(cls).__setattr__(cls, wrappername, property(fget, fset, fdel, doc))
|
type(cls).__setattr__(cls, wrappername, property(fget, fset, fdel, doc))
|
||||||
|
|
||||||
|
|
@ -138,11 +144,11 @@ class SharedMemoryModelBase(ModelBase):
|
||||||
fieldname = field.name
|
fieldname = field.name
|
||||||
if not fieldname.startswith("db_"):
|
if not fieldname.startswith("db_"):
|
||||||
continue
|
continue
|
||||||
wrappername = fieldname == "id" and "dbid" or fieldname.replace("db_", "")
|
wrappername = "dbid" if fieldname == "id" else fieldname.replace("db_", "")
|
||||||
if not hasattr(cls, wrappername):
|
if not hasattr(cls, wrappername):
|
||||||
# makes sure not to overload manually created wrappers on the model
|
# makes sure not to overload manually created wrappers on the model
|
||||||
#print "wrapping %s -> %s" % (fieldname, wrappername)
|
#print "wrapping %s -> %s" % (fieldname, wrappername)
|
||||||
create_wrapper(cls, fieldname, wrappername)
|
create_wrapper(cls, fieldname, wrappername, editable=field.editable)
|
||||||
|
|
||||||
class SharedMemoryModel(Model):
|
class SharedMemoryModel(Model):
|
||||||
# CL: setting abstract correctly to allow subclasses to inherit the default
|
# CL: setting abstract correctly to allow subclasses to inherit the default
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue