Nearly complete support for Tags
These changes allow all of the rest of the code to use tags in sql as they were used on mongo. It's not efficient at all, as changing tags usually means to remove all old tags and adding all new. The only problem here is: Old slugs for tags are not removed, because they're shared across all MediaTags and dropping orphans is not always easy.
This commit is contained in:
parent
ebc0e38239
commit
de91730336
@ -77,3 +77,19 @@ class GMGTableBase(object):
|
||||
|
||||
|
||||
Base = declarative_base(cls=GMGTableBase)
|
||||
|
||||
|
||||
class DictReadAttrProxy(object):
|
||||
"""
|
||||
Maps read accesses to obj['key'] to obj.key
|
||||
and hides all the rest of the obj
|
||||
"""
|
||||
def __init__(self, proxied_obj):
|
||||
self.proxied_obj = proxied_obj
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
return getattr(self.proxied_obj, key)
|
||||
except AttributeError:
|
||||
raise KeyError("%r is not an attribute on %r"
|
||||
% (key, self.proxied_obj))
|
||||
|
@ -26,7 +26,7 @@ from sqlalchemy.sql.expression import desc
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
|
||||
from mediagoblin.db.sql.extratypes import PathTupleWithSlashes
|
||||
from mediagoblin.db.sql.base import Base
|
||||
from mediagoblin.db.sql.base import Base, DictReadAttrProxy
|
||||
from mediagoblin.db.mixin import UserMixin, MediaEntryMixin
|
||||
|
||||
|
||||
@ -101,6 +101,13 @@ class MediaEntry(Base, MediaEntryMixin):
|
||||
creator=lambda k, v: MediaFile(name=k, file_path=v)
|
||||
)
|
||||
|
||||
tags_helper = relationship("MediaTag",
|
||||
cascade="all, delete-orphan"
|
||||
)
|
||||
tags = association_proxy("tags_helper", "dict_view",
|
||||
creator=lambda v: MediaTag(name=v["name"], slug=v["slug"])
|
||||
)
|
||||
|
||||
## TODO
|
||||
# media_data
|
||||
# attachment_files
|
||||
@ -153,22 +160,47 @@ class Tag(Base):
|
||||
id = Column(Integer, primary_key=True)
|
||||
slug = Column(Unicode, nullable=False, unique=True)
|
||||
|
||||
def __repr__(self):
|
||||
return "<Tag %r: %r>" % (self.id, self.slug)
|
||||
|
||||
@classmethod
|
||||
def find_or_new(cls, slug):
|
||||
t = cls.query.filter_by(slug=slug).first()
|
||||
if t is not None:
|
||||
return t
|
||||
return cls(slug=slug)
|
||||
|
||||
|
||||
class MediaTag(Base):
|
||||
__tablename__ = "media_tags"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
media_entry = Column(
|
||||
Integer, ForeignKey(MediaEntry.id),
|
||||
nullable=False)
|
||||
tag = Column(Integer, ForeignKey('tags.id'), nullable=False)
|
||||
name = Column(Unicode)
|
||||
media_entry = Column(
|
||||
Integer, ForeignKey('media_entries.id'),
|
||||
nullable=False)
|
||||
# created = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint('tag', 'media_entry'),
|
||||
{})
|
||||
|
||||
tag_helper = relationship(Tag)
|
||||
slug = association_proxy('tag_helper', 'slug',
|
||||
creator=Tag.find_or_new
|
||||
)
|
||||
|
||||
def __init__(self, name, slug):
|
||||
Base.__init__(self)
|
||||
self.name = name
|
||||
self.tag_helper = Tag.find_or_new(slug)
|
||||
|
||||
@property
|
||||
def dict_view(self):
|
||||
"""A dict like view on this object"""
|
||||
return DictReadAttrProxy(self)
|
||||
|
||||
|
||||
class MediaComment(Base):
|
||||
__tablename__ = "media_comments"
|
||||
|
@ -69,7 +69,7 @@ def edit_media(request, media):
|
||||
else:
|
||||
media.title = unicode(request.POST['title'])
|
||||
media.description = unicode(request.POST.get('description'))
|
||||
media['tags'] = convert_to_tag_list_of_dicts(
|
||||
media.tags = convert_to_tag_list_of_dicts(
|
||||
request.POST.get('tags'))
|
||||
|
||||
media.description_html = cleaned_markdown_conversion(
|
||||
|
@ -74,7 +74,7 @@ def submit_start(request):
|
||||
entry.uploader = request.user._id
|
||||
|
||||
# Process the user's folksonomy "tags"
|
||||
entry['tags'] = convert_to_tag_list_of_dicts(
|
||||
entry.tags = convert_to_tag_list_of_dicts(
|
||||
request.POST.get('tags'))
|
||||
|
||||
# Generate a slug from the title
|
||||
|
Loading…
x
Reference in New Issue
Block a user