mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Fixed an issue where saving an attribute/tag would make duplicates.
This commit is contained in:
parent
a6187ed997
commit
a1b596a847
3 changed files with 41 additions and 24 deletions
|
|
@ -1,14 +1,9 @@
|
|||
from django.contrib import admin
|
||||
from django.contrib.admin import ModelAdmin
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.forms import Textarea
|
||||
from src.typeclasses.models import Attribute, Tag
|
||||
|
||||
|
||||
class PickledWidget(Textarea):
|
||||
pass
|
||||
|
||||
|
||||
class TagAdmin(admin.ModelAdmin):
|
||||
fields = ('db_key', 'db_category', 'db_data')
|
||||
|
||||
|
|
@ -26,7 +21,7 @@ class AttributeInline(admin.TabularInline):
|
|||
"""
|
||||
# Set this to the through model of your desired M2M when subclassing.
|
||||
model = None
|
||||
extra = 3
|
||||
extra = 1
|
||||
#form = AttributeForm
|
||||
fields = ('attribute', 'key', 'value', 'strvalue')
|
||||
raw_id_fields = ('attribute',)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import weakref
|
|||
from django.db import models
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
from django.utils.encoding import smart_str
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
|
|
@ -46,7 +47,8 @@ from src.server.models import ServerConfig
|
|||
from src.typeclasses import managers
|
||||
from src.locks.lockhandler import LockHandler
|
||||
from src.utils import logger
|
||||
from src.utils.utils import make_iter, is_iter, to_str, inherits_from, LazyLoadHandler
|
||||
from src.utils.utils import (
|
||||
make_iter, is_iter, to_str, inherits_from, LazyLoadHandler)
|
||||
from src.utils.dbserialize import to_pickle, from_pickle
|
||||
from src.utils.picklefield import PickledObjectField
|
||||
|
||||
|
|
@ -69,7 +71,6 @@ _DA = object.__delattr__
|
|||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
#class Attribute(SharedMemoryModel):
|
||||
class Attribute(SharedMemoryModel):
|
||||
"""
|
||||
Abstract django model.
|
||||
|
|
@ -99,20 +100,33 @@ class Attribute(SharedMemoryModel):
|
|||
# These database fields are all set using their corresponding properties,
|
||||
# named same as the field, but withtout the db_* prefix.
|
||||
db_key = models.CharField('key', max_length=255, db_index=True)
|
||||
# access through the value property
|
||||
db_value = PickledObjectField('value', null=True)
|
||||
# string-specific storage for quick look-up
|
||||
db_strvalue = models.TextField('strvalue', null=True, blank=True)
|
||||
# optional categorization of attribute
|
||||
db_category = models.CharField('category', max_length=128, db_index=True, blank=True, null=True)
|
||||
db_value = PickledObjectField(
|
||||
'value', null=True,
|
||||
help_text="The data returned when the attribute is accessed. Must be "
|
||||
"written as a Python literal if editing through the admin "
|
||||
"interface.")
|
||||
db_strvalue = models.TextField(
|
||||
'strvalue', null=True, blank=True,
|
||||
help_text="String-specific storage for quick look-up")
|
||||
db_category = models.CharField(
|
||||
'category', max_length=128, db_index=True, blank=True, null=True,
|
||||
help_text="Optional categorization of attribute.")
|
||||
# Lock storage
|
||||
db_lock_storage = models.TextField('locks', blank=True)
|
||||
# Which model of object this Attribute is attached to (A natural key like objects.dbobject)
|
||||
db_model = models.CharField('model', max_length=32, db_index=True, blank=True, null=True)
|
||||
db_lock_storage = models.TextField(
|
||||
'locks', blank=True,
|
||||
help_text="Lockstrings for this object are stored here.")
|
||||
db_model = models.CharField(
|
||||
'model', max_length=32, db_index=True, blank=True, null=True,
|
||||
help_text="Which model of object this attribute is attached to (A "
|
||||
"natural key like objects.dbobject). You should not change "
|
||||
"this value unless you know what you are doing.")
|
||||
# subclass of Attribute (None or nick)
|
||||
db_attrtype = models.CharField('attrtype', max_length=16, db_index=True, blank=True, null=True)
|
||||
db_attrtype = models.CharField(
|
||||
'attrtype', max_length=16, db_index=True, blank=True, null=True,
|
||||
help_text="Subclass of Attribute (None or nick)")
|
||||
# time stamp
|
||||
db_date_created = models.DateTimeField('date_created', editable=False, auto_now_add=True)
|
||||
db_date_created = models.DateTimeField(
|
||||
'date_created', editable=False, auto_now_add=True)
|
||||
|
||||
# Database manager
|
||||
objects = managers.AttributeManager()
|
||||
|
|
@ -226,10 +240,14 @@ class AttributeHandler(object):
|
|||
self._cache = None
|
||||
|
||||
def _recache(self):
|
||||
if not self._attrtype:
|
||||
attrtype = Q(db_attrtype=None) | Q(db_attrtype='')
|
||||
else:
|
||||
attrtype = Q(db_attrtype=self._attrtype)
|
||||
self._cache = dict(("%s-%s" % (to_str(attr.db_key).lower(),
|
||||
attr.db_category.lower() if attr.db_category else None), attr)
|
||||
for attr in getattr(self.obj, self._m2m_fieldname).filter(
|
||||
db_model=self._model, db_attrtype=self._attrtype))
|
||||
db_model=self._model).filter(attrtype))
|
||||
#set_attr_cache(self.obj, self._cache) # currently only for testing
|
||||
|
||||
def has(self, key, category=None):
|
||||
|
|
@ -551,12 +569,16 @@ class TagHandler(object):
|
|||
self._model = "%s.%s" % ContentType.objects.get_for_model(obj).natural_key()
|
||||
self._cache = None
|
||||
|
||||
|
||||
def _recache(self):
|
||||
"Update cache from database field"
|
||||
if not self._tagtype:
|
||||
tagtype = Q(db_tagtype='') | Q(db_tagtype__isnull=True)
|
||||
else:
|
||||
tagtype = Q(db_tagtype=self._tagtype)
|
||||
self._cache = dict(("%s-%s" % (tag.db_key, tag.db_category), tag)
|
||||
for tag in getattr(self.obj, self._m2m_fieldname).filter(
|
||||
db_model=self._model, db_tagtype=self._tagtype))
|
||||
for tag in getattr(
|
||||
self.obj, self._m2m_fieldname).filter(
|
||||
db_model=self._model).filter(tagtype))
|
||||
|
||||
def add(self, tag, category=None, data=None):
|
||||
"Add a new tag to the handler. Tag is a string or a list of strings."
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ class PickledFormField(CharField):
|
|||
value = 'None'
|
||||
try:
|
||||
return literal_eval(value)
|
||||
except ValueError:
|
||||
except (ValueError, SyntaxError):
|
||||
raise ValidationError(self.error_messages['invalid'])
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue