Show More
@@ -1,11 +1,11 b'' | |||
|
1 | from boards.abstracts.sticker_factory import StickerFactory | |
|
1 | from django.contrib import admin | |
|
2 | from django.urls import reverse | |
|
3 | from django.utils.translation import ugettext_lazy as _ | |
|
4 | ||
|
5 | from boards.models import Post, Tag, Ban, Thread, Banner, Attachment, \ | |
|
6 | KeyPair, GlobalId, TagAlias, STATUS_ACTIVE | |
|
2 | 7 | from boards.models.attachment import FILE_TYPES_IMAGE, AttachmentSticker, \ |
|
3 | 8 | StickerPack |
|
4 | from django.contrib import admin | |
|
5 | from django.utils.translation import ugettext_lazy as _ | |
|
6 | from django.core.urlresolvers import reverse | |
|
7 | from boards.models import Post, Tag, Ban, Thread, Banner, Attachment, \ | |
|
8 | KeyPair, GlobalId, TagAlias, STATUS_ACTIVE | |
|
9 | 9 | from boards.models.source import ThreadSource |
|
10 | 10 | |
|
11 | 11 |
@@ -1,4 +1,5 b'' | |||
|
1 | 1 | # coding=utf-8 |
|
2 | from xml import etree | |
|
2 | 3 | |
|
3 | 4 | import re |
|
4 | 5 | import random |
@@ -7,7 +8,7 b' import bbcode' | |||
|
7 | 8 | from urllib.parse import unquote |
|
8 | 9 | |
|
9 | 10 | from django.core.exceptions import ObjectDoesNotExist |
|
10 |
from django. |
|
|
11 | from django.urls import reverse | |
|
11 | 12 | |
|
12 | 13 | import boards |
|
13 | 14 | from boards import settings |
@@ -19,10 +19,11 b' class BanMiddleware:' | |||
|
19 | 19 | anything |
|
20 | 20 | """ |
|
21 | 21 | |
|
22 | def __init__(self): | |
|
23 | pass | |
|
22 | def __init__(self, get_response): | |
|
23 | self.get_response = get_response | |
|
24 | 24 | |
|
25 | def process_view(self, request, view_func, view_args, view_kwargs): | |
|
25 | def __call__(self, request): | |
|
26 | response = self.get_response(request) | |
|
26 | 27 | |
|
27 | 28 | if request.path != '/banned/': |
|
28 | 29 | ip = utils.get_client_ip(request) |
@@ -33,12 +34,21 b' class BanMiddleware:' | |||
|
33 | 34 | if not ban.can_read: |
|
34 | 35 | return redirect('banned') |
|
35 | 36 | |
|
37 | return response | |
|
38 | ||
|
36 | 39 | |
|
37 | 40 | class TimezoneMiddleware(object): |
|
38 | def process_request(self, request): | |
|
41 | def __init__(self, get_response): | |
|
42 | self.get_response = get_response | |
|
43 | ||
|
44 | def __call__(self, request): | |
|
45 | response = self.get_response(request) | |
|
46 | ||
|
39 | 47 | tzname = request.session.get(SESSION_TIMEZONE) |
|
40 | 48 | if tzname: |
|
41 | 49 | timezone.activate(pytz.timezone(tzname)) |
|
42 | 50 | else: |
|
43 | 51 | timezone.deactivate() |
|
44 | 52 | |
|
53 | return response | |
|
54 |
@@ -106,7 +106,7 b' class Migration(migrations.Migration):' | |||
|
106 | 106 | migrations.AddField( |
|
107 | 107 | model_name='post', |
|
108 | 108 | name='thread_new', |
|
109 | field=models.ForeignKey(null=True, default=None, to='boards.Thread'), | |
|
109 | field=models.ForeignKey(on_delete=models.CASCADE, null=True, default=None, to='boards.Thread'), | |
|
110 | 110 | preserve_default=True, |
|
111 | 111 | ), |
|
112 | 112 | ] |
@@ -21,7 +21,7 b' class Migration(migrations.Migration):' | |||
|
21 | 21 | migrations.AddField( |
|
22 | 22 | model_name='post', |
|
23 | 23 | name='thread', |
|
24 | field=models.ForeignKey(related_name='pt+', to='boards.Thread', default=None, null=True), | |
|
24 | field=models.ForeignKey(on_delete=models.CASCADE, related_name='pt+', to='boards.Thread', default=None, null=True), | |
|
25 | 25 | preserve_default=False, |
|
26 | 26 | ), |
|
27 | 27 | migrations.RunPython(first_thread_to_thread), |
@@ -25,7 +25,7 b' class Migration(migrations.Migration):' | |||
|
25 | 25 | migrations.AlterField( |
|
26 | 26 | model_name='post', |
|
27 | 27 | name='thread', |
|
28 | field=models.ForeignKey(to='boards.Thread', related_name='pt+'), | |
|
28 | field=models.ForeignKey(on_delete=models.CASCADE, to='boards.Thread', related_name='pt+'), | |
|
29 | 29 | preserve_default=True, |
|
30 | 30 | ), |
|
31 | 31 | migrations.RunPython(clean_duplicate_tags), |
@@ -16,7 +16,7 b' class Migration(migrations.Migration):' | |||
|
16 | 16 | fields=[ |
|
17 | 17 | ('id', models.AutoField(serialize=False, verbose_name='ID', auto_created=True, primary_key=True)), |
|
18 | 18 | ('name', models.TextField()), |
|
19 | ('post', models.ForeignKey(to='boards.Post')), | |
|
19 | ('post', models.ForeignKey(on_delete=models.CASCADE, to='boards.Post')), | |
|
20 | 20 | ], |
|
21 | 21 | options={ |
|
22 | 22 | }, |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | from __future__ import unicode_literals |
|
3 |
from django. |
|
|
3 | from django.urls import reverse | |
|
4 | 4 | |
|
5 | 5 | from django.db import models, migrations |
|
6 | 6 |
@@ -17,7 +17,7 b' class Migration(migrations.Migration):' | |||
|
17 | 17 | ('id', models.AutoField(serialize=False, primary_key=True, verbose_name='ID', auto_created=True)), |
|
18 | 18 | ('title', models.TextField()), |
|
19 | 19 | ('text', models.TextField()), |
|
20 | ('post', models.ForeignKey(to='boards.Post')), | |
|
20 | ('post', models.ForeignKey(on_delete=models.CASCADE, to='boards.Post')), | |
|
21 | 21 | ], |
|
22 | 22 | ), |
|
23 | 23 | ] |
@@ -37,12 +37,12 b' class Migration(migrations.Migration):' | |||
|
37 | 37 | ('key_type', models.TextField()), |
|
38 | 38 | ('key', models.TextField()), |
|
39 | 39 | ('signature', models.TextField()), |
|
40 | ('global_id', models.ForeignKey(to='boards.GlobalId')), | |
|
40 | ('global_id', models.ForeignKey(on_delete=models.CASCADE, to='boards.GlobalId')), | |
|
41 | 41 | ], |
|
42 | 42 | ), |
|
43 | 43 | migrations.AddField( |
|
44 | 44 | model_name='post', |
|
45 | 45 | name='global_id', |
|
46 | field=models.OneToOneField(to='boards.GlobalId', null=True, blank=True), | |
|
46 | field=models.OneToOneField(on_delete=models.CASCADE, to='boards.GlobalId', null=True, blank=True), | |
|
47 | 47 | ), |
|
48 | 48 | ] |
@@ -14,6 +14,6 b' class Migration(migrations.Migration):' | |||
|
14 | 14 | migrations.AddField( |
|
15 | 15 | model_name='tag', |
|
16 | 16 | name='parent', |
|
17 | field=models.ForeignKey(to='boards.Tag', null=True), | |
|
17 | field=models.ForeignKey(on_delete=models.CASCADE, to='boards.Tag', null=True), | |
|
18 | 18 | ), |
|
19 | 19 | ] |
@@ -14,6 +14,6 b' class Migration(migrations.Migration):' | |||
|
14 | 14 | migrations.AlterField( |
|
15 | 15 | model_name='tag', |
|
16 | 16 | name='parent', |
|
17 | field=models.ForeignKey(related_name='children', null=True, to='boards.Tag'), | |
|
17 | field=models.ForeignKey(on_delete=models.CASCADE, related_name='children', null=True, to='boards.Tag'), | |
|
18 | 18 | ), |
|
19 | 19 | ] |
@@ -14,6 +14,6 b' class Migration(migrations.Migration):' | |||
|
14 | 14 | migrations.AlterField( |
|
15 | 15 | model_name='tag', |
|
16 | 16 | name='parent', |
|
17 | field=models.ForeignKey(blank=True, related_name='children', to='boards.Tag', null=True), | |
|
17 | field=models.ForeignKey(on_delete=models.CASCADE, blank=True, related_name='children', to='boards.Tag', null=True), | |
|
18 | 18 | ), |
|
19 | 19 | ] |
@@ -173,9 +173,9 b' class StickerPack(models.Model):' | |||
|
173 | 173 | |
|
174 | 174 | |
|
175 | 175 | class AttachmentSticker(models.Model): |
|
176 | attachment = models.ForeignKey('Attachment') | |
|
176 | attachment = models.ForeignKey('Attachment', on_delete=models.CASCADE) | |
|
177 | 177 | name = models.TextField(unique=True) |
|
178 | stickerpack = models.ForeignKey('StickerPack') | |
|
178 | stickerpack = models.ForeignKey('StickerPack', on_delete=models.CASCADE) | |
|
179 | 179 | |
|
180 | 180 | def __str__(self): |
|
181 | 181 | # Local stickers do not have a sticker pack |
@@ -1,17 +1,10 b'' | |||
|
1 | import re | |
|
2 | ||
|
3 | from PIL import Image | |
|
4 | ||
|
5 | 1 |
|
|
6 | 2 | from django.contrib.staticfiles.templatetags.staticfiles import static |
|
7 | 3 | from django.core.files.images import get_image_dimensions |
|
8 | 4 | from django.template.defaultfilters import filesizeformat |
|
9 | from django.core.urlresolvers import reverse | |
|
10 | from django.utils.translation import ugettext_lazy as _, ungettext_lazy | |
|
11 | 5 | |
|
6 | from boards import settings | |
|
12 | 7 | from boards.utils import get_domain, cached_result, get_extension |
|
13 | from boards import settings | |
|
14 | ||
|
15 | 8 | |
|
16 | 9 | FILE_STUB_IMAGE = 'images/file.png' |
|
17 | 10 | FILE_STUB_URL = 'url' |
@@ -4,7 +4,7 b' from django.db import models' | |||
|
4 | 4 | class Banner(models.Model): |
|
5 | 5 | title = models.TextField() |
|
6 | 6 | text = models.TextField(blank=True, null=True) |
|
7 | post = models.ForeignKey('Post') | |
|
7 | post = models.ForeignKey('Post', on_delete=models.CASCADE) | |
|
8 | 8 | |
|
9 | 9 | def __str__(self): |
|
10 | 10 | return self.title |
@@ -1,8 +1,13 b'' | |||
|
1 | 1 | import uuid |
|
2 | ||
|
2 | 3 | import hashlib |
|
3 | 4 | import re |
|
5 | from django.db import models | |
|
6 | from django.db.models import TextField | |
|
7 | from django.template.defaultfilters import truncatewords, striptags | |
|
8 | from django.template.loader import render_to_string | |
|
9 | from django.urls import reverse | |
|
4 | 10 | |
|
5 | from boards import settings | |
|
6 | 11 | from boards.abstracts.tripcode import Tripcode |
|
7 | 12 | from boards.models import Attachment, KeyPair, GlobalId |
|
8 | 13 | from boards.models.attachment import FILE_TYPES_IMAGE |
@@ -10,12 +15,6 b' from boards.models.base import Viewable' | |||
|
10 | 15 | from boards.models.post.export import get_exporter, DIFF_TYPE_JSON |
|
11 | 16 | from boards.models.post.manager import PostManager, NO_IP |
|
12 | 17 | from boards.utils import datetime_to_epoch |
|
13 | from django.core.exceptions import ObjectDoesNotExist | |
|
14 | from django.core.urlresolvers import reverse | |
|
15 | from django.db import models | |
|
16 | from django.db.models import TextField, QuerySet, F | |
|
17 | from django.template.defaultfilters import truncatewords, striptags | |
|
18 | from django.template.loader import render_to_string | |
|
19 | 18 | |
|
20 | 19 | CSS_CLS_HIDDEN_POST = 'hidden_post' |
|
21 | 20 | CSS_CLS_DEAD_POST = 'dead_post' |
@@ -87,7 +86,8 b' class Post(models.Model, Viewable):' | |||
|
87 | 86 | blank=True, related_name='refposts', |
|
88 | 87 | db_index=True) |
|
89 | 88 | refmap = models.TextField(null=True, blank=True) |
|
90 |
thread = models.ForeignKey('Thread', |
|
|
89 | thread = models.ForeignKey('Thread', on_delete=models.CASCADE, | |
|
90 | db_index=True, related_name='replies') | |
|
91 | 91 | |
|
92 | 92 | url = models.TextField() |
|
93 | 93 | uid = models.TextField() |
@@ -122,4 +122,4 b' class Signature(models.Model):' | |||
|
122 | 122 | key = models.TextField() |
|
123 | 123 | signature = models.TextField() |
|
124 | 124 | |
|
125 | global_id = models.ForeignKey('GlobalId') | |
|
125 | global_id = models.ForeignKey('GlobalId', on_delete=models.CASCADE) |
@@ -29,7 +29,7 b' class ThreadSource(models.Model):' | |||
|
29 | 29 | app_label = 'boards' |
|
30 | 30 | |
|
31 | 31 | name = models.TextField() |
|
32 | thread = models.ForeignKey('Thread') | |
|
32 | thread = models.ForeignKey('Thread', on_delete=models.CASCADE) | |
|
33 | 33 | timestamp = models.DateTimeField() |
|
34 | 34 | source = models.TextField() |
|
35 | 35 | source_type = models.CharField(max_length=SOURCE_TYPE_MAX_LENGTH, |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | import hashlib |
|
2 |
from django. |
|
|
2 | from django.urls import reverse | |
|
3 | 3 | from django.db import models |
|
4 | 4 | from django.db.models import Count, Q |
|
5 | 5 | from django.utils.translation import get_language |
@@ -37,8 +37,8 b' class TagAlias(models.Model, Viewable):' | |||
|
37 | 37 | name = models.CharField(max_length=100, db_index=True) |
|
38 | 38 | locale = models.CharField(max_length=10, db_index=True) |
|
39 | 39 | |
|
40 |
parent = models.ForeignKey('Tag', null=True, |
|
|
41 | related_name='aliases') | |
|
40 | parent = models.ForeignKey('Tag', on_delete=models.CASCADE, null=True, | |
|
41 | blank=True, related_name='aliases') | |
|
42 | 42 | |
|
43 | 43 | |
|
44 | 44 | class TagManager(models.Manager): |
@@ -91,8 +91,8 b' class Tag(models.Model, Viewable):' | |||
|
91 | 91 | required = models.BooleanField(default=False, db_index=True) |
|
92 | 92 | description = models.TextField(blank=True) |
|
93 | 93 | |
|
94 |
parent = models.ForeignKey('Tag', null=True, |
|
|
95 | related_name='children') | |
|
94 | parent = models.ForeignKey('Tag', on_delete=models.CASCADE, null=True, | |
|
95 | blank=True, related_name='children') | |
|
96 | 96 | |
|
97 | 97 | def get_name(self): |
|
98 | 98 | return self.aliases.get(locale=DEFAULT_LOCALE).name |
@@ -40,6 +40,6 b' class Notification(models.Model):' | |||
|
40 | 40 | |
|
41 | 41 | objects = NotificationManager() |
|
42 | 42 | |
|
43 | post = models.ForeignKey('Post') | |
|
43 | post = models.ForeignKey('Post', on_delete=models.CASCADE) | |
|
44 | 44 | name = models.TextField() |
|
45 | 45 |
@@ -1,13 +1,9 b'' | |||
|
1 | 1 | import re |
|
2 | ||
|
2 | from django import template | |
|
3 | 3 | from django.shortcuts import get_object_or_404 |
|
4 | from django import template | |
|
5 | 4 | from django.utils.text import re_tag |
|
6 | from django.core.urlresolvers import reverse | |
|
7 | 5 | |
|
8 | 6 | from boards.mdx_neboard import LINE_BREAK_HTML |
|
9 | from boards import settings | |
|
10 | ||
|
11 | 7 | |
|
12 | 8 | IMG_ACTION_URL = '[<a href="{}">{}</a>]' |
|
13 | 9 | REGEX_NEWLINE = re.compile(LINE_BREAK_HTML) |
@@ -1,4 +1,6 b'' | |||
|
1 | 1 | from django.conf.urls import url |
|
2 | from django.urls import path | |
|
3 | from django.views.i18n import JavaScriptCatalog | |
|
2 | 4 | |
|
3 | 5 | from boards import views |
|
4 | 6 | from boards.rss import AllThreadsFeed, TagThreadsFeed, ThreadPostsFeed |
@@ -12,12 +14,8 b' from boards.views.search import BoardSea' | |||
|
12 | 14 | from boards.views.static import StaticPageView |
|
13 | 15 | from boards.views.sync import get_post_sync_data, response_get, response_list |
|
14 | 16 | from boards.views.tag_gallery import TagGalleryView |
|
15 | from boards.views.translation import cached_javascript_catalog | |
|
16 | 17 | from boards.views.utils import UtilsView |
|
17 | 18 | |
|
18 | js_info_dict = { | |
|
19 | 'packages': ('boards',), | |
|
20 | } | |
|
21 | 19 | |
|
22 | 20 | urlpatterns = [ |
|
23 | 21 | # /boards/ |
@@ -61,8 +59,7 b' urlpatterns = [' | |||
|
61 | 59 | url(r'^thread/(?P<post_id>\d+)/rss/$', ThreadPostsFeed()), |
|
62 | 60 | |
|
63 | 61 | # i18n |
|
64 | url(r'^jsi18n/$', cached_javascript_catalog, js_info_dict, | |
|
65 | name='js_info_dict'), | |
|
62 | path('jsi18n/', JavaScriptCatalog.as_view(packages=['boards']), name='js_info_dict'), | |
|
66 | 63 | |
|
67 | 64 | # API |
|
68 | 65 | url(r'^api/post/(?P<post_id>\d+)/$', api.get_post, name="get_post"), |
@@ -1,9 +0,0 b'' | |||
|
1 | __author__ = 'neko259' | |
|
2 | ||
|
3 | from django.views.decorators.cache import cache_page | |
|
4 | from django.views.i18n import javascript_catalog | |
|
5 | ||
|
6 | ||
|
7 | @cache_page(86400) | |
|
8 | def cached_js_catalog(request, domain='djangojs', packages=None): | |
|
9 | return javascript_catalog(request, domain, packages) |
@@ -1,10 +1,8 b'' | |||
|
1 | from django.core.urlresolvers import reverse | |
|
2 | from django.core.files import File | |
|
3 | from django.core.files.temp import NamedTemporaryFile | |
|
4 | 1 |
|
|
5 | 2 | from django.db import transaction |
|
6 | 3 | from django.http import Http404 |
|
7 | 4 | from django.shortcuts import render, redirect |
|
5 | from django.urls import reverse | |
|
8 | 6 | from django.utils.decorators import method_decorator |
|
9 | 7 | from django.views.decorators.csrf import csrf_protect |
|
10 | 8 | |
@@ -16,9 +14,9 b' from boards.forms import ThreadForm, Pla' | |||
|
16 | 14 | from boards.models import Post, Thread, Ban |
|
17 | 15 | from boards.views.banned import BannedView |
|
18 | 16 | from boards.views.base import BaseBoardView, CONTEXT_FORM |
|
19 | from boards.views.posting_mixin import PostMixin | |
|
20 | 17 | from boards.views.mixins import FileUploadMixin, PaginatedMixin,\ |
|
21 | 18 |
|
|
19 | from boards.views.posting_mixin import PostMixin | |
|
22 | 20 | |
|
23 | 21 | FORM_TAGS = 'tags' |
|
24 | 22 | FORM_TEXT = 'text' |
@@ -1,4 +1,4 b'' | |||
|
1 |
from django. |
|
|
1 | from django.urls import reverse | |
|
2 | 2 | from django.shortcuts import render |
|
3 | 3 | |
|
4 | 4 | from boards import settings |
@@ -1,7 +1,7 b'' | |||
|
1 | 1 | from django.shortcuts import render |
|
2 | 2 | from django.views.generic import View |
|
3 | 3 | from django.db.models import Q |
|
4 |
from django. |
|
|
4 | from django.urls import reverse | |
|
5 | 5 | |
|
6 | 6 | from boards.abstracts.paginator import get_paginator |
|
7 | 7 | from boards.forms import SearchForm, PlainErrorList |
@@ -1,9 +1,9 b'' | |||
|
1 | from django.core.urlresolvers import reverse | |
|
2 | 1 |
|
|
2 | from django.urls import reverse | |
|
3 | 3 | |
|
4 | 4 | from boards import settings |
|
5 | 5 | from boards.abstracts.paginator import get_paginator |
|
6 |
from boards.models import |
|
|
6 | from boards.models import TagAlias | |
|
7 | 7 | from boards.views.base import BaseBoardView |
|
8 | 8 | from boards.views.mixins import PaginatedMixin |
|
9 | 9 |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | from django.shortcuts import get_object_or_404, redirect |
|
2 |
from django. |
|
|
2 | from django.urls import reverse | |
|
3 | 3 | |
|
4 | 4 | from boards.abstracts.settingsmanager import get_settings_manager, \ |
|
5 | 5 | SETTING_FAVORITE_TAGS, SETTING_HIDDEN_TAGS |
@@ -1,24 +1,18 b'' | |||
|
1 | from django.contrib.auth.decorators import permission_required | |
|
2 | ||
|
3 | 1 |
|
|
4 | from django.core.urlresolvers import reverse | |
|
5 | 2 | from django.http import Http404 |
|
6 | 3 | from django.shortcuts import get_object_or_404, render, redirect |
|
7 | from django.template.context_processors import csrf | |
|
4 | from django.urls import reverse | |
|
8 | 5 | from django.utils.decorators import method_decorator |
|
9 | 6 | from django.views.decorators.csrf import csrf_protect |
|
10 | 7 | from django.views.generic.edit import FormMixin |
|
11 | from django.utils import timezone | |
|
12 | from django.utils.dateformat import format | |
|
13 | 8 | |
|
14 |
from boards import utils |
|
|
9 | from boards import utils | |
|
15 | 10 | from boards.abstracts.settingsmanager import get_settings_manager |
|
16 | 11 | from boards.forms import PostForm, PlainErrorList |
|
17 | 12 | from boards.models import Post |
|
18 | 13 | from boards.views.base import BaseBoardView, CONTEXT_FORM |
|
19 | 14 | from boards.views.mixins import DispatcherMixin, PARAMETER_METHOD |
|
20 | 15 | from boards.views.posting_mixin import PostMixin |
|
21 | import neboard | |
|
22 | 16 | |
|
23 | 17 | REQ_POST_ID = 'post_id' |
|
24 | 18 |
@@ -104,7 +104,7 b' TEMPLATES = [{' | |||
|
104 | 104 | }] |
|
105 | 105 | |
|
106 | 106 | |
|
107 |
MIDDLEWARE |
|
|
107 | MIDDLEWARE = [ | |
|
108 | 108 | 'django.middleware.http.ConditionalGetMiddleware', |
|
109 | 109 | 'django.contrib.sessions.middleware.SessionMiddleware', |
|
110 | 110 | 'django.middleware.locale.LocaleMiddleware', |
@@ -179,7 +179,7 b' POSTING_DELAY = 20 # seconds' | |||
|
179 | 179 | SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' |
|
180 | 180 | |
|
181 | 181 | # Debug middlewares |
|
182 |
MIDDLEWARE |
|
|
182 | MIDDLEWARE += [ | |
|
183 | 183 | 'debug_toolbar.middleware.DebugToolbarMiddleware', |
|
184 | 184 | ] |
|
185 | 185 |
@@ -13,7 +13,7 b' urlpatterns = [' | |||
|
13 | 13 | # Uncomment the admin/doc line below to enable admin documentation: |
|
14 | 14 | # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), |
|
15 | 15 | |
|
16 |
url(r'^admin/', |
|
|
16 | url(r'^admin/', admin.site.urls, name='admin'), | |
|
17 | 17 | url(r'^', include('boards.urls')), |
|
18 | 18 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) |
|
19 | 19 |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now