-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmodels.py
166 lines (132 loc) · 5.76 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
from django.conf import settings
from django.contrib.sites.models import Site
from django.db import models
from django.utils.six import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from parler.fields import TranslatedField
from parler.models import TranslatableModel, TranslatedFields
from parler.utils.context import switch_language
from fluent_contents.models import PlaceholderField, ContentItemRelation
from fluent_faq.urlresolvers import faq_reverse
from fluent_faq.managers import FaqQuestionManager, FaqCategoryManager
from fluent_utils.softdeps.taggit import TagsMixin
def _get_current_site():
return Site.objects.get_current().pk
class FaqBaseModel(TranslatableModel):
"""
Shared functionality for published content.
"""
# SEO
meta_keywords = models.CharField(_('keywords'), max_length=255, blank=True, default='', help_text=_("When this field is not filled in, the the tags will be used."))
meta_description = models.CharField(_('description'), max_length=255, blank=True, default='', help_text=_("When this field is not filled in, the contents or intro text will be used."))
# Metadata
author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('author'), editable=False)
creation_date = models.DateTimeField(_('creation date'), editable=False, auto_now_add=True)
modification_date = models.DateTimeField(_('last modification'), editable=False, auto_now=True)
parent_site = models.ForeignKey(Site, editable=False, default=_get_current_site)
class Meta:
abstract = True
def get_absolute_url(self):
return self.default_url
@property
def default_url(self):
"""
The internal implementation of :func:`get_absolute_url`.
This function can be used when overriding :func:`get_absolute_url` in the settings.
For example::
ABSOLUTE_URL_OVERRIDES = {
'fluent_faq.FaqQuestion': lambda o: "http://example.com" + o.default_url
}
"""
with switch_language(self):
root = faq_reverse('faqquestion_index', ignore_multiple=True, language_code=self.get_current_language())
return root + self.get_relative_url()
@property
def url(self):
"""
The URL of the entry, provided for template code.
"""
return self.get_absolute_url()
def get_relative_url(self):
raise NotImplementedError("get_relative_url")
@python_2_unicode_compatible
class FaqCategory(FaqBaseModel):
"""
Topic of the FAQ
"""
# Be compatible with django-orderable table layout,
# unfortunately, there isn't a good canonical version of it yet.
order = models.PositiveIntegerField(db_index=True, blank=True, null=True)
title = TranslatedField(any_language=True)
translations = TranslatedFields(
title = models.CharField(_("title"), max_length=200),
slug = models.SlugField(_("slug")),
)
objects = FaqCategoryManager()
class Meta:
verbose_name = _("FAQ Category")
verbose_name_plural = _("FAQ Categories")
ordering = ('order', 'creation_date')
def __str__(self):
# self.title is configured with any_language=True, so always returns a value.
return self.title
def get_relative_url(self):
return u'{0}/'.format(self.slug)
@property
def faq_questions(self):
"""
Fetch the active FAQ questions in this category.
"""
return self.questions.active_translations()
@python_2_unicode_compatible
class FaqQuestion(TagsMixin, FaqBaseModel):
"""
Category in the FAQ.
"""
# This is a separate model instead of using django-categories because:
# - content needs to be placed on the category.
# - the title and slug can be translated!
# Be compatible with django-orderable table layout,
# unfortunately, there isn't a good canonical version of it yet.
order = models.PositiveIntegerField(db_index=True, blank=True, null=True)
title = TranslatedField(any_language=True)
translations = TranslatedFields(
title = models.CharField(_("title"), max_length=200),
slug = models.SlugField(_("slug")),
)
contents = PlaceholderField("faq_answer", verbose_name=_("answer"))
contentitem_set = ContentItemRelation() # this makes sure the admin can find all deleted objects too.
# Organisation
category = models.ForeignKey(FaqCategory, verbose_name=_("Category"), related_name='questions')
objects = FaqQuestionManager()
class Meta:
verbose_name = _("FAQ Question")
verbose_name_plural = _("FAQ Questions")
ordering = ('order', 'creation_date')
def __str__(self):
# self.title is configured with any_language=True, so always returns a value.
return self.title
def get_relative_url(self):
"""
Return the link path from the archive page.
"""
# Return the link style, using the permalink style setting.
return u'{0}{1}/'.format(self.category.get_relative_url(), self.slug)
def similar_objects(self, num=None, **filters):
"""
Find similar objects using related tags.
"""
#TODO: filter appsettings.FLUENT_FAQ_FILTER_SITE_ID:
# filters.setdefault('parent_site', self.parent_site_id)
# FIXME: Using super() doesn't work, calling directly.
return TagsMixin.similar_objects(self, num=num, **filters)
def _register_anyurlfield_type():
try:
from any_urlfield.models import AnyUrlField
from any_urlfield.forms.widgets import SimpleRawIdWidget
except ImportError:
pass
else:
AnyUrlField.register_model(FaqQuestion, widget=SimpleRawIdWidget(FaqQuestion))
if 'any_urlfield' in settings.INSTALLED_APPS:
_register_anyurlfield_type()