ArticlesApp
This commit is contained in:
SDE
2023-08-28 18:05:50 +03:00
parent 4354d1369d
commit 237524be8e
17 changed files with 549 additions and 22 deletions

0
ArticlesApp/__init__.py Normal file
View File

159
ArticlesApp/admin.py Normal file
View File

@@ -0,0 +1,159 @@
## -*- coding: utf8 -*-
__author__ = 'SDE'
from django.contrib import admin
from ArticlesApp.models import ArticleModel, UserPageModel
from sets.admin import *
# class Admin_ArticlesPageSets(Admin_BaseIconModel):
#
# fieldsets = (
# (None, {
# 'classes': ['wide'],
# 'fields': (
# 'name', 'url', 'description', 'picture'
# )
#
#
# }),
# (u'Управление отображением страницы', {
# 'classes': ['wide'],
# 'fields': (
# # ('serviceBlockStateShow'),
# # ('articlesCountInBlock'),
# # ('advicesCountInBlock'),
# )
# }),
#
# ('SEO', {
# 'classes': ['wide', 'collapse'],
# 'fields': ('seo_title', 'seo_description','seo_keywords', 'seo_text')
# }),
#
# )
#
# prepopulated_fields = {"url": ("name",)}
# list_display = ('name', 'url', 'seo_title', 'createDT')
# # list_editable = ('dish_price', 'allowForDelivery', 'dish_maxDiscount','dish_rating',
# # 'dish_enabled')
# # filter_horizontal = ['service_works',]
# # date_hierarchy = 'createDT'
# # list_filter = ('device_name', 'vendor',)
# list_display_links = ('name',)
# save_on_top = True
#
# def has_add_permission(self, request):
# return not ArticlesPageSets.objects.all().count() > 0
#
# def has_delete_permission(self, request, obj=None):
# if not request.user.is_superuser:
# return False
# else:
# return True
#
# admin.site.register(ArticlesPageSets,Admin_ArticlesPageSets)
class Admin_Article(Admin_Trans_BaseModelViewPage):
fieldsets = (
(None, {
'classes': ['wide'],
'fields': (('name'),
('url'),
# 'pub_DT',
'picture',
# ('devices'),
)
}),
(u'Статья', {
'classes': ['wide'],
'fields': (
'description', 'text',
)
}),
('SEO', {
'classes': ['wide', 'collapse'],
'fields': ('seo_title', 'seo_description','seo_keywords')
}),
)
prepopulated_fields = {"url": ("name",)}
list_display = (
# 'image_thumb',
'name', 'url', 'order', 'createDT')
list_editable = ('order',) # 'allowForDelivery', 'dish_maxDiscount','dish_rating',
# 'dish_enabled')
# filter_horizontal = ['sites']
date_hierarchy = 'createDT'
list_filter = ('enable', 'createDT')
list_display_links = (
'name',
# 'image_thumb',
)
save_on_top = True
admin.site.register(ArticleModel, Admin_Article)
# class Admin_ArticleSliders(admin.TabularInline):
# model = ArticleModel.SliderSets.through
class Admin_UserPage(Admin_Trans_BaseModelViewPage):
fieldsets = (
(None, {
'classes': ['wide'],
'fields': (('name'),
('url'),
# 'pub_DT',
# ('devices'),
)
}),
(u'Статья', {
'classes': ['wide'],
'fields': ('picture', 'description', 'text')
}),
('SEO', {
'classes': ['wide', 'collapse'],
'fields': ('seo_title', 'seo_description','seo_keywords')
}),
)
prepopulated_fields = {"url": ("name",)}
list_display = (
# 'image_thumb',
'name', 'url', 'order', 'seo_title', 'createDT')
list_editable = ('order', ) # 'allowForDelivery', 'dish_maxDiscount','dish_rating',
# 'dish_enabled')
# filter_horizontal = ['sites']
date_hierarchy = 'createDT'
list_filter = ('enable', 'createDT')
list_display_links = (
'name',
# 'image_thumb',
)
save_on_top = True
actions = ['create_copy']
def has_delete_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj and obj.url in ('for-partners', 'dealers', 'about-truenergy', 'contacts'):
return False
return True
admin.site.register(UserPageModel,Admin_UserPage)

View File

@@ -0,0 +1,103 @@
# Generated by Django 4.2.2 on 2023-08-28 17:17
import ckeditor.fields
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='ArticleModel',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_ru', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_en', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')),
('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')),
('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')),
('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')),
('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')),
('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')),
('url', models.TextField(help_text='можно изменить адрес страницы (!!! ВНИМАНИЕ !!! поисковые системы потеряют страницу и найдут лишь спустя неделю...месяц)', unique=True, verbose_name='URL привязанной страницы')),
('title', models.TextField(blank=True, null=True, verbose_name='Заголовок')),
('description', ckeditor.fields.RichTextField(blank=True, help_text='краткое описание страницы (до 240 символов)', null=True, verbose_name='Краткое описание')),
('description_ru', ckeditor.fields.RichTextField(blank=True, help_text='краткое описание страницы (до 240 символов)', null=True, verbose_name='Краткое описание')),
('description_en', ckeditor.fields.RichTextField(blank=True, help_text='краткое описание страницы (до 240 символов)', null=True, verbose_name='Краткое описание')),
('picture', models.ImageField(blank=True, null=True, upload_to='uploads/', verbose_name='Картинка')),
('visible', models.BooleanField(default=True, verbose_name='Отображать')),
('background_image_left', models.ImageField(blank=True, null=True, upload_to='', verbose_name='Левая подложка')),
('background_image_right', models.ImageField(blank=True, null=True, upload_to='', verbose_name='Правая подложка')),
('seo_title', models.CharField(blank=True, max_length=250, null=True, verbose_name='Title (80 знаков)')),
('seo_title_ru', models.CharField(blank=True, max_length=250, null=True, verbose_name='Title (80 знаков)')),
('seo_title_en', models.CharField(blank=True, max_length=250, null=True, verbose_name='Title (80 знаков)')),
('seo_description', models.CharField(blank=True, max_length=250, null=True, verbose_name='Description (150 знаков)')),
('seo_description_ru', models.CharField(blank=True, max_length=250, null=True, verbose_name='Description (150 знаков)')),
('seo_description_en', models.CharField(blank=True, max_length=250, null=True, verbose_name='Description (150 знаков)')),
('seo_keywords', models.CharField(blank=True, max_length=250, null=True, verbose_name='Keywords (200 знаков)')),
('seo_keywords_ru', models.CharField(blank=True, max_length=250, null=True, verbose_name='Keywords (200 знаков)')),
('seo_keywords_en', models.CharField(blank=True, max_length=250, null=True, verbose_name='Keywords (200 знаков)')),
('seo_text', ckeditor.fields.RichTextField(blank=True, null=True, verbose_name='Текст SEO статьи')),
('seo_text_ru', ckeditor.fields.RichTextField(blank=True, null=True, verbose_name='Текст SEO статьи')),
('seo_text_en', ckeditor.fields.RichTextField(blank=True, null=True, verbose_name='Текст SEO статьи')),
('FAQ_title', models.CharField(blank=True, max_length=250, null=True, verbose_name='FAQ Заголовок')),
('text', ckeditor.fields.RichTextField(verbose_name='Текст')),
('text_ru', ckeditor.fields.RichTextField(null=True, verbose_name='Текст')),
('text_en', ckeditor.fields.RichTextField(null=True, verbose_name='Текст')),
],
options={
'verbose_name': 'Статья',
'verbose_name_plural': 'Статьи',
},
),
migrations.CreateModel(
name='UserPageModel',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_ru', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_en', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')),
('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')),
('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')),
('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')),
('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')),
('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')),
('url', models.TextField(help_text='можно изменить адрес страницы (!!! ВНИМАНИЕ !!! поисковые системы потеряют страницу и найдут лишь спустя неделю...месяц)', unique=True, verbose_name='URL привязанной страницы')),
('title', models.TextField(blank=True, null=True, verbose_name='Заголовок')),
('description', ckeditor.fields.RichTextField(blank=True, help_text='краткое описание страницы (до 240 символов)', null=True, verbose_name='Краткое описание')),
('description_ru', ckeditor.fields.RichTextField(blank=True, help_text='краткое описание страницы (до 240 символов)', null=True, verbose_name='Краткое описание')),
('description_en', ckeditor.fields.RichTextField(blank=True, help_text='краткое описание страницы (до 240 символов)', null=True, verbose_name='Краткое описание')),
('picture', models.ImageField(blank=True, null=True, upload_to='uploads/', verbose_name='Картинка')),
('visible', models.BooleanField(default=True, verbose_name='Отображать')),
('background_image_left', models.ImageField(blank=True, null=True, upload_to='', verbose_name='Левая подложка')),
('background_image_right', models.ImageField(blank=True, null=True, upload_to='', verbose_name='Правая подложка')),
('seo_title', models.CharField(blank=True, max_length=250, null=True, verbose_name='Title (80 знаков)')),
('seo_title_ru', models.CharField(blank=True, max_length=250, null=True, verbose_name='Title (80 знаков)')),
('seo_title_en', models.CharField(blank=True, max_length=250, null=True, verbose_name='Title (80 знаков)')),
('seo_description', models.CharField(blank=True, max_length=250, null=True, verbose_name='Description (150 знаков)')),
('seo_description_ru', models.CharField(blank=True, max_length=250, null=True, verbose_name='Description (150 знаков)')),
('seo_description_en', models.CharField(blank=True, max_length=250, null=True, verbose_name='Description (150 знаков)')),
('seo_keywords', models.CharField(blank=True, max_length=250, null=True, verbose_name='Keywords (200 знаков)')),
('seo_keywords_ru', models.CharField(blank=True, max_length=250, null=True, verbose_name='Keywords (200 знаков)')),
('seo_keywords_en', models.CharField(blank=True, max_length=250, null=True, verbose_name='Keywords (200 знаков)')),
('seo_text', ckeditor.fields.RichTextField(blank=True, null=True, verbose_name='Текст SEO статьи')),
('seo_text_ru', ckeditor.fields.RichTextField(blank=True, null=True, verbose_name='Текст SEO статьи')),
('seo_text_en', ckeditor.fields.RichTextField(blank=True, null=True, verbose_name='Текст SEO статьи')),
('FAQ_title', models.CharField(blank=True, max_length=250, null=True, verbose_name='FAQ Заголовок')),
('text', ckeditor.fields.RichTextField(verbose_name='Текст')),
('text_ru', ckeditor.fields.RichTextField(null=True, verbose_name='Текст')),
('text_en', ckeditor.fields.RichTextField(null=True, verbose_name='Текст')),
],
options={
'verbose_name': 'Пользовательская страница',
'verbose_name_plural': 'Пользовательские страницы',
},
),
]

View File

37
ArticlesApp/models.py Normal file
View File

@@ -0,0 +1,37 @@
# -*- coding: utf8 -*-
__author__ = 'sync'
from django.db import models
from BaseModels.base_models import BaseModelViewPage, BaseModel
from ckeditor.fields import RichTextField
from django.utils.translation import gettext_lazy as _
# class ArticlesPageSets(BaseModelViewPage):
#
# class Meta:
# verbose_name = 'Настройки страницы архива статей'
# verbose_name_plural = 'Настройки страницы архива статей'
class UserPageModel(BaseModelViewPage):
# pub_DT = models.DateTimeField(verbose_name=u'Дата и время публикации', auto_created=True)
text = RichTextField(verbose_name=u'Текст')
class Meta:
verbose_name=u'Пользовательская страница'
verbose_name_plural =u'Пользовательские страницы'
# unique_together = ('url', 'region')
# managed=True
# app_label = u'ArticlesApp'
class ArticleModel(BaseModelViewPage):
# pub_DT = models.DateTimeField(verbose_name=u'Дата и время публикации', auto_created=True)
text = RichTextField(verbose_name=u'Текст')
class Meta:
verbose_name=u'Статья'
verbose_name_plural =u'Статьи'

16
ArticlesApp/tests.py Normal file
View File

@@ -0,0 +1,16 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
from modeltranslation.translator import translator, TranslationOptions, register
from .models import *
@register(ArticleModel)
class Article_TranslationOptions(TranslationOptions):
fields = (
'name', 'description', 'seo_title', 'seo_description', 'seo_keywords', 'seo_text',
'text'
)
# translator.register(ArticleModel, Article_TranslationOptions)
@register(UserPageModel)
class UserPage_TranslationOptions(TranslationOptions):
fields = (
'name', 'description', 'seo_title', 'seo_description', 'seo_keywords', 'seo_text',
'text'
)
# translator.register(UserPageModel, UserPage_TranslationOptions)

5
ArticlesApp/urls.py Normal file
View File

@@ -0,0 +1,5 @@
from django.urls import path
from .views import *
urlpatterns = [
]

View File

@@ -0,0 +1,9 @@
from django.urls import path
from .views import *
urlpatterns = [
path('articles/', ArticlesPageView, name=u'articles'),
path('articles/<int:year>/', ArticlesPageView, name=u'articles_by_year'),
path('article/<str:art_url>/', ArticlesOnePageView, name=u'article_one'),
path('page/<str:page_url>/', UserPageView, name=u'page_one'),
]

145
ArticlesApp/views.py Normal file
View File

@@ -0,0 +1,145 @@
# -*- coding: utf8 -*-
from .models import *
from datetime import datetime, date
from django.http import Http404, HttpResponse
from django.template import loader
# from django.contrib.auth.decorators import login_required
# from BaseModels.search_optimization.ld_json.ld_article_news import get_ld_article_news
# from django.contrib.sites.shortcuts import get_current_site
def get_flat_pages_links_Dict(site):
flat_pages_links = UserPageModel.objects.filter(
url__in=('about-truenergy', 'for-partners', 'contacts'),
sites=site
).values_list('url', flat=True)
return {'flat_pages_links': flat_pages_links}
def get_article_breadcrumbs(request, art):
# print('get_article_breadcrumbs')
half_count = art.articlesCountInBlock / 2
art_List = ArticleModel.objects.filter(enable=True, article_DT__gte=art.article_DT).order_by(
'article_DT')[:half_count]
artListDown = ArticleModel.objects.filter(enable=True, article_DT__lt=art.article_DT).order_by(
'-article_DT')[:art.articlesCountInBlock-len(art_List)]
if len(artListDown)<half_count:
art_List = ArticleModel.objects.filter(enable=True, article_DT__gte=art.article_DT).order_by(
'article_DT')[:art.articlesCountInBlock-len(artListDown)]
art_List = list(art_List)
art_List.reverse()
artlist = art_List + list(artListDown)
# print('artlist',artlist)
return artlist
def get_user_pages_breadcrumbs(request, art):
from ArticlesApp.models import UserPageModel
# print('get_user_pages_breadcrumbs')
half_count = art.articlesCountInBlock / 2
art_List = UserPageModel.objects.filter(enable=True, article_DT__gte=art.article_DT).order_by(
'article_DT')[:half_count]
artListDown = UserPageModel.objects.filter(enable=True, article_DT__lt=art.article_DT).order_by(
'-article_DT')[:art.articlesCountInBlock-len(art_List)]
if len(artListDown)<half_count:
art_List = UserPageModel.objects.filter(enable=True, article_DT__gte=art.article_DT).order_by(
'article_DT')[:art.articlesCountInBlock-len(artListDown)]
art_List = list(art_List)
art_List.reverse()
artlist = art_List + list(artListDown)
# print('artlist',artlist)
return artlist
# @login_required(login_url='/admin/')
def ArticlesPageView(request, year=None):
kwargs = {}
if year:
try:
year = int(year)
kwargs.update({'createDT__year': year})
except:
raise Http404
arts = ArticleModel.objects.filter(**kwargs)
Dict = {
'articles': arts
}
t = loader.get_template('pages/p_articles.html')
return HttpResponse(t.render(Dict, request))
# @login_required(login_url='/admin/')
def UserPageView(request, page_url):
kwargs = {
'url': page_url
}
try:
art = UserPageModel.objects.get(**kwargs)
except UserPageModel.DoesNotExist:
raise Http404
# service = ServiceModel.objects.filter(enable=True, artDevs=art)[0]
# article_breadcrumbs = get_user_pages_breadcrumbs(request,art)
# print('article_breadcrumbs',article_breadcrumbs)
Dict = {
'art' : art,
'user_page' : True,
# 'service' : service,
# 'article_breadcrumbs' : article_breadcrumbs
}
t = loader.get_template('pages/p_article.html')
return HttpResponse(t.render(Dict, request))
# @login_required(login_url='/admin/')
def ArticlesOnePageView(request, art_url):
kwargs = {
'url': art_url
}
try:
art = UserPageModel.objects.get(**kwargs)
except UserPageModel.DoesNotExist:
raise Http404
# article_breadcrumbs = get_article_breadcrumbs(request, art)
# print('article_breadcrumbs',article_breadcrumbs)
Dict = {
'art' : art,
# 'article_breadcrumbs' : article_breadcrumbs
}
t = loader.get_template('pages/p_user_page.html')
return HttpResponse(t.render(Dict, request))

View File

@@ -221,6 +221,8 @@ def create_or_change_route_ajax(request, route_id=None):
try: try:
data = request.POST data = request.POST
if not data:
data = json.loads(request.body)
route = None route = None
if route_id: if route_id:

View File

@@ -53,6 +53,7 @@ INSTALLED_APPS = [
'AuthApp', 'AuthApp',
'RoutesApp', 'RoutesApp',
'ReferenceDataApp', 'ReferenceDataApp',
'ArticlesApp',
] ]

View File

@@ -28,6 +28,7 @@ urlpatterns += i18n_patterns(
path('reference_data/', include('ReferenceDataApp.js_urls')), path('reference_data/', include('ReferenceDataApp.js_urls')),
path('', include('ArticlesApp.urls_translate')),
) )

View File

@@ -44,29 +44,29 @@ class Admin_BaseBlock(Admin_BaseIconModel):
class Admin_BaseModelViewPage(Admin_BaseIconModel): class Admin_BaseModelViewPage(Admin_BaseIconModel):
pass pass
def get_fieldsets(self, request, obj=None): # def get_fieldsets(self, request, obj=None):
fieldsets = super(Admin_BaseModelViewPage, self).get_fieldsets(request, obj) # fieldsets = super(Admin_BaseModelViewPage, self).get_fieldsets(request, obj)
# fieldsets = deepcopy(self.fieldsets) # # fieldsets = deepcopy(self.fieldsets)
seo_block = ( # seo_block = (
'SEO', { # 'SEO', {
'classes': ['wide', 'collapse'], # 'classes': ['wide', 'collapse'],
'fields': ( # 'fields': (
'seo_title', 'seo_description', # 'seo_title', 'seo_description',
'seo_keywords', # 'seo_keywords',
'seo_text' # 'seo_text'
) # )
}) # })
# fieldsets[0][1]['fields'].append('url') # # fieldsets[0][1]['fields'].append('url')
fieldsets.append(seo_block) # fieldsets.append(seo_block)
return fieldsets # return fieldsets
def get_prepopulated_fields(self, request, obj=None): # def get_prepopulated_fields(self, request, obj=None):
if 'url' in self.get_fieldsets(request, obj): # if 'url' in self.get_fieldsets(request, obj):
return {"url": ("name",)} # return {"url": ("name",)}
else: # else:
return {} # return {}
#
inlines = [AdminStacked_FAQitem] # inlines = [AdminStacked_FAQitem]

View File

@@ -0,0 +1,7 @@
{% extends "tb_base.html" %}
{% block content %}
<div>{{ art.name }}</div>
<div>{{ art.description }}</div>
<div>{{ art.text|safe }}</div>
{% endblock %}

View File

@@ -0,0 +1,9 @@
{% extends "tb_base.html" %}
{% block content %}
{% for art in articles %}
<div>{{ art.name }}</div>
<div>{{ art.description }}</div>
<div>{{ art.text|safe }}</div>
{% endfor %}
{% endblock %}

View File

@@ -0,0 +1,7 @@
{% extends "tb_base.html" %}
{% block content %}
<div>{{ art.name }}</div>
<div>{{ art.description }}</div>
<div>{{ art.text|safe }}</div>
{% endblock %}