blog

models.py

1
from django.contrib.auth.models import User  # For logging purposes
2
from django.utils import translation
3
from django.template.defaultfilters import slugify
4
from django.db import models
5
import datetime
6
import os
7
8
def post_title_directory(instance, filename):
9
    """ Files will be uploaded to MEDIA_ROOT/blog/<year of publishing>/<blog
10
    title>
11
    The blog title is determined by the text before the first period (".") in
12
    the filename. So if the file has the name "Trains are bæ.en.md", the file
13
    will be stored in "blog/<this year>/Trains are bæ". Name your files
14
    properly!
15
    It should also be noted that all files are stored in the same folder if they
16
    belong to the same blogpost, regardless of language. The titles that are
17
    displayed to the user however, should be the titles of the files themselves,
18
    which should be in the native language. So if a blog post is titled
19
    "Universities of Belgium", its Dutch counterpart should be titled
20
    "Universiteiten van België", so the correct title can be derived from the
21
    filename.
22
23
    Recommended way to name the uploaded file: "<name of blog post in language
24
    it's written>.org". This removes the maximum amount of redundancy (e.g. the
25
    language of the file can be derived from the title, no ".fr.org" or something
26
    like that necessary), and can directly be used for the end user (the title
27
    is what should be displayed).
28
    """
29
    english_file_name = os.path.basename(instance.english_file.name) # TODO: Test if this returns the file name!
30
    english_title = english_file_name.rpartition(".")[0]
31
    year = datetime.date.today().year
32
33
    return "blog/{0}/{1}/{2}".format(year, english_title, filename)
34
35
class Post(models.Model):
36
    """ Represents a blog post. The title of the blog post is determnined by the name
37
    of the files.
38
    A blog post can be in 5 different languages: German, Spanish, English, French,
39
    and Dutch. For all these languages, a seperate field exists. Thus, a
40
    translated blog post has a seperate file for each translation, and is
41
    seperated from Django's internationalization/localization system.
42
    Only the English field is mandatory. The others may contain a value if a
43
    translated version exists, which will be displayed accordingly.
44
    """
45
    published = models.DateTimeField(auto_now_add=True)
46
    english_file = models.FileField(upload_to=post_title_directory, blank=False)
47
    dutch_file = models.FileField(upload_to=post_title_directory, blank=False)
48
    french_file = models.FileField(upload_to=post_title_directory, blank=True)
49
    german_file = models.FileField(upload_to=post_title_directory, blank=True)
50
    spanish_file = models.FileField(upload_to=post_title_directory, blank=True)
51
52
    title_en = models.CharField(max_length=64, unique=True, blank=False)
53
    title_nl = models.CharField(max_length=64, unique=True, blank=False)
54
    title_fr = models.CharField(max_length=64, blank=True)
55
    title_de = models.CharField(max_length=64, blank=True)
56
    title_es = models.CharField(max_length=64, blank=True)
57
    # PostgreSQL sees two null values as not unique, therefore I can't ask for unique names.
58
59
    slug_en  = models.SlugField(unique=True, blank=False, allow_unicode=True)
60
    slug_nl  = models.SlugField(unique=True, blank=False, allow_unicode=True)
61
    slug_fr  = models.SlugField(blank=True, allow_unicode=True)
62
    slug_de  = models.SlugField(blank=True, allow_unicode=True)
63
    slug_es  = models.SlugField(blank=True, allow_unicode=True)
64
65
    def __str__(self):
66
        return self.slug("en")
67
68
    def text_file(self, language_code=translation.get_language()):
69
        if language_code == "en":
70
            return self.english_file
71
        elif language_code == "nl":
72
            return self.dutch_file
73
        elif language_code == "de":
74
            if self.german_file is None:
75
                return self.english_file
76
            else:
77
                return self.german_file
78
        elif language_code == "fr":
79
            if self.french_file is None:
80
                return self.english_file
81
            else:
82
                return self.french_file
83
        elif language_code == "es":
84
            if self.spanish_file is None:
85
                return self.english_file
86
            else:
87
                return self.spanish_file
88
        return self.english_file
89
90
    def title(self, language_code=translation.get_language()):
91
        if language_code == "en":
92
            return self.title_en
93
        elif language_code == "nl":
94
            return self.title_nl
95
        elif language_code == "de":
96
            if self.title_de == "":
97
                return self.title_en
98
            else:
99
                return self.title_de
100
        elif language_code == "fr":
101
            if self.title_fr == "":
102
                return self.title_en
103
            else:
104
                return self.title_fr
105
        elif language_code == "es":
106
            if self.title_es == "":
107
                return self.title_en
108
            else:
109
                return self.title_es
110
        return self.title_en
111
112
    def slug(self, language_code=translation.get_language()):
113
        """ Returns a slug of the requested language, or None if no version exists in that language. """
114
        if language_code == "en":
115
            return self.slug_en
116
        elif language_code == "nl":
117
            return self.slug_nl
118
        elif language_code == "de":
119
            if self.slug_de == "":
120
                return self.slug_en
121
            else:
122
                return self.slug_de
123
        elif language_code == "fr":
124
            if self.slug_fr == "":
125
                return self.slug_en
126
            else:
127
                return self.slug_fr
128
        elif language_code == "es":
129
            if self.slug_es == "":
130
                return self.slug_en
131
            else:
132
                return self.slug_es
133
        return self.slug_en
134
135
class Comment(models.Model):
136
    """ Represents a comment on a blog post.
137
    Comments are not filtered by language; a
138
    comment made by someone reading the article in Dutch, that's written in
139
    Dutch, will show up (unedited) for somebody whom's reading the Spanish
140
    version.
141
    """
142
    date = models.DateTimeField(auto_now_add=True)
143
    name = models.CharField(max_length=64)
144
    text = models.TextField(max_length=1000)  # Should be more than enough.
145
    post = models.ForeignKey(
146
        Post,
147
        on_delete=models.CASCADE,
148
        null=False,
149
        )
150
    class meta:
151
        ordering = ['date']  # When printed, prints the oldest comment first.
152
153
class FeedItem(models.Model):
154
    """ An item that shows up in the RSS feed."""
155
    title = models.CharField(max_length=64)
156
    added = models.DateTimeField(auto_now_add=True)
157
    description = models.CharField(max_length=400)
158
    link = models.URLField()
159