From a2c4b55f5befdf94fe7a8ad3aee2b016e62e5309 Mon Sep 17 00:00:00 2001 From: Ivan Kovalkovskyi Date: Wed, 7 Oct 2015 15:17:08 +0300 Subject: [PATCH] separate theme for blog(Article model) --- article/admin.py | 8 ++- article/forms.py | 12 ++-- article/models.py | 3 +- article/views.py | 8 +-- templates/admin/includes/admin_nav.html | 1 + .../theme/theme_blog_confirm_delete.html | 11 ++++ templates/admin/theme/theme_blog_list.html | 65 +++++++++++++++++++ templates/admin/theme/theme_blog_new.html | 49 ++++++++++++++ templates/client/article/article.html | 4 +- theme/admin.py | 43 ++++++++++-- theme/admin_urls.py | 6 ++ theme/forms.py | 17 ++++- theme/models.py | 24 +++++++ theme/views.py | 3 - 14 files changed, 227 insertions(+), 27 deletions(-) create mode 100644 templates/admin/theme/theme_blog_confirm_delete.html create mode 100644 templates/admin/theme/theme_blog_list.html create mode 100644 templates/admin/theme/theme_blog_new.html diff --git a/article/admin.py b/article/admin.py index ff178cee..377f3b13 100644 --- a/article/admin.py +++ b/article/admin.py @@ -125,12 +125,14 @@ def article_change(request, url): return render_to_response('article_add.html', args) #----------------------- -from django.views.generic import ListView, FormView +from django.views.generic import FormView +from functions.custom_views import ListView from forms import BlogForm class BlogList(ListView): model = Article - template_name = 'article/article_admin_list.html' + template_name = 'admin/article/article_admin_list.html' + paginate_by = settings.ADMIN_PAGINATION def get_queryset(self): return self.model.objects.blogs() @@ -168,7 +170,7 @@ class BlogView(FormView): if self.obj: article = self.obj data = {} - data['theme'] = [item.id for item in article.theme.all()] + data['theme'] = [item.id for item in article.blog_theme.all()] if article.exposition: data['exposition'] = article.exposition.id if article.conference: diff --git a/article/forms.py b/article/forms.py index 8810abe7..d7c2fcd8 100644 --- a/article/forms.py +++ b/article/forms.py @@ -12,14 +12,14 @@ from functions.form_check import translit_with_separator #models from models import Article from accounts.models import User -from theme.models import Theme, Tag +from theme.models import Theme, Tag, ThemeBlog from exposition.models import Exposition from conference.models import Conference class BlogForm(forms.Form): type = Article.blog - theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.exclude(article__id=None), required=False, + theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=ThemeBlog.objects.all(), required=False, widget=forms.SelectMultiple(attrs={'style':'width: 550px'})) publish_date = forms.DateField(label=u'Дата публикации', input_formats=['%Y-%m-%d', '%d.%m.%Y'], required=False) tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False) @@ -61,9 +61,9 @@ class BlogForm(forms.Form): # fill translated fields and save object fill_with_signal(Article, article, data) # fill manytomany fields - article.theme.clear() + article.blog_theme.clear() article.tag.clear() - article.theme.add(*Theme.objects.filter(id__in=data['theme'])) + article.blog_theme.add(*ThemeBlog.objects.filter(id__in=data['theme'])) article.tag.add(*Tag.objects.filter(id__in=data['tag'])) #for item in data['theme']: # article.theme.add(item.id)#.id cause select uses queryset @@ -258,7 +258,7 @@ class BlogForm(forms.ModelForm): class ArticleFilterForm(forms.Form): theme = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False, - choices=[(item.id, item.name) for item in Theme.objects.language().filter(article__type=1).exclude(article__id=None).distinct()]) + choices=[(item.id, item.name) for item in ThemeBlog.objects.language().distinct()]) tag = forms.CharField(label=_(u'Теги:'), widget=forms.HiddenInput(), required=False) ''' @@ -284,7 +284,7 @@ class BlogFilterForm(forms.Form): super(BlogFilterForm, self).__init__(*args, **kwargs) ids = [item['theme'] for item in list(Article.objects.blogs().values('theme').distinct())] self.fields['theme'] = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False, - choices=[(item.id, item.name) for item in Theme.objects.language().filter(id__in=ids)]) + choices=[(item.id, item.name) for item in ThemeBlog.objects.language().filter(id__in=ids)]) class NewsFilterForm(forms.Form): diff --git a/article/models.py b/article/models.py index aa252baf..4a3e77f2 100644 --- a/article/models.py +++ b/article/models.py @@ -14,7 +14,6 @@ from functions.form_check import translit_with_separator from django.core.cache import cache - class ArticleManager(TranslationManager): cache_time = 60 def safe_get(self, **kwargs): @@ -60,7 +59,6 @@ class ArticleManager(TranslationManager): cache.set(key, blogs, self.cache_time) return blogs - return list(self.blogs().filter(publish_date__isnull=False).order_by('-main_page', '-publish_date')[:3]) class Article(TranslatableModel): """ @@ -81,6 +79,7 @@ class Article(TranslatableModel): old_id = models.IntegerField(blank=True, null=True) logo = ImageField(upload_to='articles_preview', blank=True) theme = models.ManyToManyField('theme.Theme') + blog_theme = models.ManyToManyField('theme.ThemeBlog') tag = models.ManyToManyField('theme.Tag', blank=True, null=True) author = models.ForeignKey('accounts.User', verbose_name='Автор', on_delete=models.PROTECT, related_name='articles') diff --git a/article/views.py b/article/views.py index 7b5c68ec..06932d0b 100644 --- a/article/views.py +++ b/article/views.py @@ -5,7 +5,7 @@ from functions.custom_views import ListView from django.http import HttpResponse from models import Article from forms import ArticleFilterForm -from theme.models import Tag, Theme +from theme.models import Tag, Theme, ThemeBlog from meta.views import MetadataMixin @@ -71,7 +71,7 @@ class BlogList(MetadataMixin, ListView): themes = self.request.GET.getlist('theme') if themes: - qs = qs.filter(theme__id__in=themes) + qs = qs.filter(blog_theme__id__in=themes) tags = self.request.GET.getlist('tag') if u'' in tags: @@ -180,10 +180,10 @@ class BlogsFilterCatalog(MetadataMixin, ListView): self.filter_object = tag qs = Article.objects.blogs().filter(tag=tag) else: - theme = get_object_or_404(Theme, url=slug) + theme = get_object_or_404(ThemeBlog, url=slug) self.kwargs['theme'] = theme self.filter_object = theme - qs = Article.objects.blogs().filter(theme = theme) + qs = Article.objects.blogs().filter(blog_theme = theme) year = self.kwargs.get('year') if year: diff --git a/templates/admin/includes/admin_nav.html b/templates/admin/includes/admin_nav.html index 25226d51..f70cb26a 100644 --- a/templates/admin/includes/admin_nav.html +++ b/templates/admin/includes/admin_nav.html @@ -40,6 +40,7 @@
  • Страна
  • Город
  • Тематики
  • +
  • Тематики для блогов
  • Теги
  • Услуги
  • Главная страница
  • diff --git a/templates/admin/theme/theme_blog_confirm_delete.html b/templates/admin/theme/theme_blog_confirm_delete.html new file mode 100644 index 00000000..ec7b8c9f --- /dev/null +++ b/templates/admin/theme/theme_blog_confirm_delete.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% block sidebar %}{% endblock %} +{% block body %} +
    {% csrf_token %} +
    +

    Вы точно хотите удалить "{{ object.name }}" ?

    + + Нет +
    +
    +{% endblock %} \ No newline at end of file diff --git a/templates/admin/theme/theme_blog_list.html b/templates/admin/theme/theme_blog_list.html new file mode 100644 index 00000000..ad6a7dcd --- /dev/null +++ b/templates/admin/theme/theme_blog_list.html @@ -0,0 +1,65 @@ +{% extends 'admin_list.html' %} + +{% block body %} + +{#
    #} +{#
    #} +{#

    Фильтры

    #} +{#
    #} +{#
    #} +{#
    #} +{# {{ form }}#} +{##} +{# #} +{#
    #} +{#
    #} +{##} +{#
    #} + +
    +
    +

    Список тем

    +
    +
    + + + + + + + + + + + + + + + + + {% for item in object_list %} + + + + + + + + + {% endfor %} + +
    idНазвание  
    {{ item.id }}{{ item.name }} + + Изменить + + + + Удалить + +
    + Добавить тематику +
    + {# pagination #} + {% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} +
    +{% endblock %} \ No newline at end of file diff --git a/templates/admin/theme/theme_blog_new.html b/templates/admin/theme/theme_blog_new.html new file mode 100644 index 00000000..9ee2b388 --- /dev/null +++ b/templates/admin/theme/theme_blog_new.html @@ -0,0 +1,49 @@ +{% extends 'base.html' %} +{% load static %} + +{% block scripts %} + + + {# selects #} + + + + + + +{% endblock %} + +{% block body %} + +
    {% csrf_token %}{{ form.errors }} +
    + {% if theme_id %} Изменить {% else %} Добавить {% endif %}тему +
    +
    +

    Информация

    +
    +
    + {% for field in form %} + + + + {% endfor %} +
    +
    + + +
    + + +
    + +
    +
    + +{% endblock %} \ No newline at end of file diff --git a/templates/client/article/article.html b/templates/client/article/article.html index e36596ee..505714e5 100644 --- a/templates/client/article/article.html +++ b/templates/client/article/article.html @@ -19,7 +19,7 @@ {% include 'client/includes/article/article_logo.html' with obj=object %}

    {{ object.main_title }}

    - {{ object.publish_date|date:"d E Y" }}{% if object.theme.all.exists %}{% include 'includes/article_theme.html' with obj=object %}{% endif %} + {{ object.publish_date|date:"d E Y" }}{% if object.blog_theme.all.exists %}{% include 'client/includes/article_theme.html' with obj=object %}{% endif %} {% if request.user.is_admin %} {% trans 'изменить' %} {% endif %} @@ -53,7 +53,7 @@ {% include 'includes/show_logo.html' with obj=blog %}

    {{ blog.main_title }}

    {{ blog.preview }}

    - {{ blog.created|date:"d E Y" }}Евгения Булавина + {{ blog.publish_date|date:"d E Y" }}Евгения Булавина {% endfor %} diff --git a/theme/admin.py b/theme/admin.py index da323984..8914587f 100644 --- a/theme/admin.py +++ b/theme/admin.py @@ -3,15 +3,13 @@ from django.shortcuts import render_to_response from django.http import HttpResponseRedirect, HttpResponse from django.core.context_processors import csrf from django.conf import settings -from django.forms.formsets import BaseFormSet, formset_factory -from django.forms.models import modelformset_factory -from django.contrib.contenttypes.models import ContentType +from django.views.generic import CreateView, UpdateView, DeleteView from django.contrib.auth.decorators import login_required #forms and models from forms import ThemeForm, TagForm, ThemeDeleteForm, TagDeleteForm, TagFilterForm, ThemeFilterForm -from models import Theme, Tag +from models import Theme, Tag, ThemeBlog #custom views -from functions.custom_views import objects_list, add_object, delete_object +from functions.custom_views import objects_list, add_object, delete_object, ListView from functions.views_help import get_referer from functions.admin_views import AdminListView @@ -170,4 +168,37 @@ class ThemeListView(AdminListView): class TagListView(AdminListView): template_name = 'admin/theme/tag_list.html' form_class = TagFilterForm - model = Tag \ No newline at end of file + model = Tag + + +from functions.custom_views import ListView +from django.core.urlresolvers import reverse_lazy +from .forms import ThemeBlogForm + + +class ThemeBlogListView(ListView): + template_name = 'admin/theme/theme_blog_list.html' + model = ThemeBlog + paginate_by = settings.ADMIN_PAGINATION + + +class ThemeBlogCreateView(CreateView): + template_name = "admin/theme/theme_blog_new.html" + model = ThemeBlog + form_class = ThemeBlogForm + success_url = reverse_lazy("theme_blog_all") + + +class ThemeBlogUpdateView(UpdateView): + template_name = "admin/theme/theme_blog_new.html" + model = ThemeBlog + form_class = ThemeBlogForm + success_url = reverse_lazy("theme_blog_all") + pk_url_kwarg = "theme_id" + + +class ThemeBlogDeleteView(DeleteView): + template_name = "admin/theme/theme_blog_confirm_delete.html" + model = ThemeBlog + success_url = reverse_lazy("theme_blog_all") + pk_url_kwarg = "theme_id" diff --git a/theme/admin_urls.py b/theme/admin_urls.py index c1803d4f..0caf5c87 100644 --- a/theme/admin_urls.py +++ b/theme/admin_urls.py @@ -1,19 +1,25 @@ # -*- coding: utf-8 -*- from django.conf.urls import patterns, include, url from admin import TagListView, ThemeListView +from .admin import ThemeBlogCreateView, ThemeBlogUpdateView, ThemeBlogDeleteView, ThemeBlogListView + urlpatterns = patterns('theme.admin', url(r'^theme/add.*/$', 'theme_add'), url(r'^tag/add.*/$', 'tag_add'), + url(r'^blog_theme/add/$', ThemeBlogCreateView.as_view(), name = 'theme_blog_new'), url(r'^theme/delete/(?P\d+)/$', 'theme_delete'), url(r'^tag/delete/(?P\d+)/$', 'tag_delete'), + url(r'^blog_theme/delete/(?P\d+)/$', ThemeBlogDeleteView.as_view(), name = 'theme_blog_delete'), url(r'^theme/change/(?P\d+).*/$', 'theme_change'), + url(r'^blog_theme/change/(?P\d+).*/$', ThemeBlogUpdateView.as_view(), name= "theme_blog_change"), url(r'^tag/change/(?P\d+).*/$', 'tag_change'), url(r'^theme/copy/(?P\d+).*/$', 'theme_copy'), url(r'^tag/copy/(?P\d+).*/$', 'tag_copy'), #url(r'^theme/all/$', 'theme_all'), #url(r'^tag/all/$', 'tag_all'), url(r'^theme/all/$', ThemeListView.as_view()), + url(r'^blog_theme/all/$', ThemeBlogListView.as_view(), name="theme_blog_all"), url(r'^tag/all/$', TagListView.as_view()), url(r'^tag/search/$', 'search_tag'), url(r'^tag/search-without-theme/$', 'search2'), diff --git a/theme/forms.py b/theme/forms.py index 7cd0512f..5f166b04 100644 --- a/theme/forms.py +++ b/theme/forms.py @@ -143,4 +143,19 @@ class ThemeFilterForm(AdminFilterForm): class TagFilterForm(AdminFilterForm): - model = Tag \ No newline at end of file + model = Tag + +from hvad.forms import TranslatableModelForm +from .models import ThemeBlog + + +class ThemeBlogForm(TranslatableModelForm): + class Meta: + model = ThemeBlog + fields = ['url', 'name', 'main_title', 'description', 'inflect'] + widgets = {'url':forms.TextInput(attrs={'required':False})} + + def save(self, commit= True): + if not 'url' in self.cleaned_data: + self.cleaned_data['url'] = translit_with_separator(self.cleaned_data['name']) + return super(ThemeBlogForm, self).save(commit=True) \ No newline at end of file diff --git a/theme/models.py b/theme/models.py index 50ece870..93908fd7 100644 --- a/theme/models.py +++ b/theme/models.py @@ -133,6 +133,30 @@ class Theme(TranslatableModel): parent = {} return parent + +class ThemeBlog(TranslatableModel): + + url = models.SlugField(unique=True, max_length=255) + + translations = TranslatedFields( + name=models.CharField(max_length=255), + main_title=models.CharField(max_length=255, blank=True), + description=models.TextField(blank=True) + ) + + inflect = models.CharField(max_length=255, blank=True) + + def __unicode__(self): + return self.lazy_translation_getter('name', unicode(self.pk)) + + def get_all_names(self): + return [item['name'] for item in self.translations.all().values('name')] + + def get_index_text(self): + translation.activate('ru') + return ' '.join(self.get_all_names()) + + from django.db import IntegrityError class Tag(TranslatableModel): """ diff --git a/theme/views.py b/theme/views.py index 1deadf9b..ce83a38a 100644 --- a/theme/views.py +++ b/theme/views.py @@ -21,11 +21,8 @@ def get_tag(request): def get_article_tags(request): - themes = request.GET.getlist('themes[]') term = request.GET['term'].capitalize() qs = Tag.objects.language().exclude(article=None).filter(article__type=1).distinct() - if themes: - qs = qs.filter(theme__id__in=themes).order_by('translations__name') if term: qs = qs.filter(translations__name__contains=term) result = [{'id': tag.id, 'label': '%s (%s)'%(tag.name, tag.theme.name)} for tag in qs]