Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-wiki
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
django-wiki
Commits
fa01cfb2
Commit
fa01cfb2
authored
Nov 12, 2014
by
benjaoming
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #337 from fsx999/master
python_2_unicode_compatible decorateur
parents
97b4a32d
e56a78a7
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
41 additions
and
11 deletions
+41
-11
wiki/admin.py
+1
-1
wiki/models/article.py
+9
-2
wiki/models/pluginbase.py
+18
-3
wiki/models/urlpath.py
+13
-5
No files found.
wiki/admin.py
View file @
fa01cfb2
...
...
@@ -69,7 +69,7 @@ class URLPathAdmin(MPTTModelAdmin):
list_filter
=
(
'site'
,
'articles__article__current_revision__deleted'
,
'articles__article__created'
,
'articles__article__modified'
)
list_display
=
(
'__
unicode
__'
,
'article'
,
'get_created'
)
list_display
=
(
'__
str
__'
,
'article'
,
'get_created'
)
def
get_created
(
self
,
instance
):
return
instance
.
article
.
created
...
...
wiki/models/article.py
View file @
fa01cfb2
...
...
@@ -7,6 +7,7 @@ from django.contrib.auth.models import Group
from
django.core.cache
import
cache
from
django.db
import
models
from
django.db.models.signals
import
post_save
,
pre_delete
from
django.utils.encoding
import
python_2_unicode_compatible
from
django.utils.safestring
import
mark_safe
from
django.utils.translation
import
ugettext_lazy
as
_
...
...
@@ -17,6 +18,7 @@ from wiki import managers
from
mptt.models
import
MPTTModel
from
django.core.urlresolvers
import
reverse
@python_2_unicode_compatible
class
Article
(
models
.
Model
):
objects
=
managers
.
ArticleManager
()
...
...
@@ -139,7 +141,7 @@ class Article(models.Model):
def
get_for_object
(
cls
,
obj
):
return
ArticleForObject
.
objects
.
get
(
object_id
=
obj
.
id
,
content_type
=
ContentType
.
objects
.
get_for_model
(
obj
))
.
article
def
__
unicode
__
(
self
):
def
__
str
__
(
self
):
if
self
.
current_revision
:
return
self
.
current_revision
.
title
obj_name
=
_
(
'Article without content (
%(id)
d)'
)
%
{
'id'
:
self
.
id
}
...
...
@@ -206,6 +208,7 @@ class ArticleForObject(models.Model):
# Do not allow several objects
unique_together
=
(
'content_type'
,
'object_id'
)
class
BaseRevisionMixin
(
models
.
Model
):
"""This is an abstract model used as a mixin: Do not override any of the
core model methods but respect the inheritor's freedom to do so itself."""
...
...
@@ -250,6 +253,8 @@ class BaseRevisionMixin(models.Model):
class
Meta
:
abstract
=
True
@python_2_unicode_compatible
class
ArticleRevision
(
BaseRevisionMixin
,
models
.
Model
):
"""This is where main revision data is stored. To make it easier to
copy, do NEVER create m2m relationships."""
...
...
@@ -273,7 +278,7 @@ class ArticleRevision(BaseRevisionMixin, models.Model):
# help_text=_('If set, the article will redirect to the contents of another article.'),
# related_name='redirect_set')
def
__
unicode
__
(
self
):
def
__
str
__
(
self
):
return
"
%
s (
%
d)"
%
(
self
.
title
,
self
.
revision_number
)
def
inherit_predecessor
(
self
,
article
):
...
...
@@ -328,10 +333,12 @@ def _clear_ancestor_cache(article):
for
ancestor
in
article
.
ancestor_objects
():
ancestor
.
article
.
clear_cache
()
def
on_article_save_clear_cache
(
instance
,
**
kwargs
):
on_article_delete_clear_cache
(
instance
,
**
kwargs
)
post_save
.
connect
(
on_article_save_clear_cache
,
Article
)
def
on_article_delete_clear_cache
(
instance
,
**
kwargs
):
_clear_ancestor_cache
(
instance
)
instance
.
clear_cache
()
...
...
wiki/models/pluginbase.py
View file @
fa01cfb2
...
...
@@ -29,6 +29,7 @@ There are three kinds of plugin base models:
from
.article
import
ArticleRevision
,
BaseRevisionMixin
from
wiki.conf
import
settings
class
ArticlePlugin
(
models
.
Model
):
"""This is the mother of all plugins. Extending from it means a deletion
of an article will CASCADE to your plugin, and the database will be kept
...
...
@@ -45,10 +46,13 @@ class ArticlePlugin(models.Model):
# Permission methods - you should override these, if they don't fit your logic.
def
can_read
(
self
,
user
):
return
self
.
article
.
can_read
(
user
)
def
can_write
(
self
,
user
):
return
self
.
article
.
can_write
(
user
)
def
can_delete
(
self
,
user
):
return
self
.
article
.
can_delete
(
user
)
def
can_moderate
(
self
,
user
):
return
self
.
article
.
can_moderate
(
user
)
...
...
@@ -61,6 +65,7 @@ class ArticlePlugin(models.Model):
# if it lives outside the wiki app.
app_label
=
settings
.
APP_LABEL
class
ReusablePlugin
(
ArticlePlugin
):
"""Extend from this model if you have a plugin that may be related to many
articles. Please note that the ArticlePlugin.article ForeignKey STAYS! This
...
...
@@ -75,9 +80,9 @@ class ReusablePlugin(ArticlePlugin):
"""
# The article on which the plugin was originally created.
# Used to apply permissions.
ArticlePlugin
.
article
.
on_delete
=
models
.
SET_NULL
ArticlePlugin
.
article
.
verbose_name
=
_
(
'original article'
)
ArticlePlugin
.
article
.
help_text
=
_
(
'Permissions are inherited from this article'
)
ArticlePlugin
.
article
.
on_delete
=
models
.
SET_NULL
ArticlePlugin
.
article
.
verbose_name
=
_
(
'original article'
)
ArticlePlugin
.
article
.
help_text
=
_
(
'Permissions are inherited from this article'
)
ArticlePlugin
.
article
.
null
=
True
ArticlePlugin
.
article
.
blank
=
True
...
...
@@ -87,10 +92,13 @@ class ReusablePlugin(ArticlePlugin):
# before handling permissions....
def
can_read
(
self
,
user
):
return
self
.
article
.
can_read
(
user
)
if
self
.
article
else
False
def
can_write
(
self
,
user
):
return
self
.
article
.
can_write
(
user
)
if
self
.
article
else
False
def
can_delete
(
self
,
user
):
return
self
.
article
.
can_delete
(
user
)
if
self
.
article
else
False
def
can_moderate
(
self
,
user
):
return
self
.
article
.
can_moderate
(
user
)
if
self
.
article
else
False
...
...
@@ -109,8 +117,10 @@ class ReusablePlugin(ArticlePlugin):
# if it lives outside the wiki app.
app_label
=
settings
.
APP_LABEL
class
SimplePluginCreateError
(
Exception
):
pass
class
SimplePlugin
(
ArticlePlugin
):
"""
Inherit from this model and make sure to specify an article when
...
...
@@ -162,6 +172,7 @@ class SimplePlugin(ArticlePlugin):
# if it lives outside the wiki app.
app_label
=
settings
.
APP_LABEL
class
RevisionPlugin
(
ArticlePlugin
):
"""
If you want your plugin to maintain revisions, extend from this one,
...
...
@@ -253,6 +264,7 @@ class RevisionPluginRevision(BaseRevisionMixin, models.Model):
# It's my art, when I disguise my body in the shape of a plane.
# (Shellac, 1993)
def
update_simple_plugins
(
**
kwargs
):
"""Every time a new article revision is created, we update all active
plugins to match this article revision"""
...
...
@@ -262,15 +274,18 @@ def update_simple_plugins(**kwargs):
# TODO: This was breaking things. SimplePlugin doesn't have a revision?
p_revisions
.
update
(
article_revision
=
instance
)
def
on_article_plugin_post_save
(
**
kwargs
):
articleplugin
=
kwargs
[
'instance'
]
articleplugin
.
article
.
clear_cache
()
def
on_reusable_plugin_post_save
(
**
kwargs
):
reusableplugin
=
kwargs
[
'instance'
]
for
article
in
reusableplugin
.
articles
.
all
():
article
.
clear_cache
()
def
on_revision_plugin_revision_post_save
(
**
kwargs
):
revision
=
kwargs
[
'instance'
]
revision
.
plugin
.
article
.
clear_cache
()
...
...
wiki/models/urlpath.py
View file @
fa01cfb2
...
...
@@ -14,6 +14,8 @@ from django.db import models, transaction
from
six.moves
import
filter
#Django 1.6 transaction API, required for 1.8+
from
django.utils.encoding
import
python_2_unicode_compatible
try
:
notrans
=
transaction
.
non_atomic_requests
except
:
...
...
@@ -33,6 +35,8 @@ from wiki.models.article import ArticleRevision, ArticleForObject, Article
log
=
logging
.
getLogger
(
__name__
)
@python_2_unicode_compatible
class
URLPath
(
MPTTModel
):
"""
Strategy: Very few fields go here, as most has to be managed through an
...
...
@@ -155,7 +159,7 @@ class URLPath(MPTTModel):
class
MPTTMeta
:
pass
def
__
unicode
__
(
self
):
def
__
str
__
(
self
):
path
=
self
.
path
return
path
if
path
else
ugettext
(
"(root)"
)
...
...
@@ -260,6 +264,7 @@ class URLPath(MPTTModel):
# Just get this once
urlpath_content_type
=
None
def
on_article_relation_save
(
**
kwargs
):
global
urlpath_content_type
instance
=
kwargs
[
'instance'
]
...
...
@@ -270,12 +275,14 @@ def on_article_relation_save(**kwargs):
post_save
.
connect
(
on_article_relation_save
,
ArticleForObject
)
class
Namespace
:
# An instance of Namespace simulates "nonlocal variable_name" declaration
# in any nested function, that is possible in Python 3. It allows assigning
# to non local variable without rebinding it local. See PEP 3104.
pass
def
on_article_delete
(
instance
,
*
args
,
**
kwargs
):
# If an article is deleted, then throw out its URLPaths
# But move all descendants to a lost-and-found node.
...
...
@@ -286,6 +293,7 @@ def on_article_delete(instance, *args, **kwargs):
# that the lost-and-found article can be deleted without being recreated!
ns
=
Namespace
()
# nonlocal namespace backported to Python 2.x
ns
.
lost_and_found
=
None
def
get_lost_and_found
():
if
ns
.
lost_and_found
:
return
ns
.
lost_and_found
...
...
@@ -294,10 +302,10 @@ def on_article_delete(instance, *args, **kwargs):
parent
=
URLPath
.
root
(),
site
=
site
)
except
URLPath
.
DoesNotExist
:
article
=
Article
(
group_read
=
True
,
group_write
=
False
,
other_read
=
False
,
other_write
=
False
)
article
=
Article
(
group_read
=
True
,
group_write
=
False
,
other_read
=
False
,
other_write
=
False
)
article
.
add_revision
(
ArticleRevision
(
content
=
_
(
'Articles who lost their parents
\n
'
'===============================
\n\n
'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment