1.8.2 media for landing

This commit is contained in:
SDE
2024-11-15 15:14:50 +03:00
parent 43153a9fdf
commit c52dbca9a1
7 changed files with 199 additions and 64 deletions

View File

@@ -29,12 +29,31 @@ class BaseModel(models.Model):
json_data = models.JSONField(verbose_name=_('Дополнительные данные'), default=dict, blank=True) json_data = models.JSONField(verbose_name=_('Дополнительные данные'), default=dict, blank=True)
media_items = GenericRelation('GeneralApp.MediaItem', related_query_name='grel_%(class)s_for_media_item')
def __str__(self): def __str__(self):
if self.name: if self.name:
return self.name return self.name
else: else:
return str(self.id) return str(self.id)
def get_media_items(self, exclude_kwargs=None):
if not exclude_kwargs:
exclude_kwargs = {}
return self.media_items.exclude(
**exclude_kwargs
).filter(
enable=True
).order_by('order')
def get_video_items(self):
exclude_kwargs = {'video': None}
return self.get_media_items(exclude_kwargs=exclude_kwargs)
def get_picture_items(self):
exclude_kwargs = {'picture': None}
return self.get_media_items(exclude_kwargs=exclude_kwargs)
def pop_node_by_name(self, node_name): def pop_node_by_name(self, node_name):
if not self.json_data or not node_name in self.json_data: if not self.json_data or not node_name in self.json_data:
return None return None
@@ -108,7 +127,6 @@ class BaseModelViewPage(BaseModel):
FAQ_title = models.CharField(max_length=250, verbose_name=_(u'FAQ Заголовок'), null=True, blank=True) FAQ_title = models.CharField(max_length=250, verbose_name=_(u'FAQ Заголовок'), null=True, blank=True)
FAQ_items = GenericRelation('GeneralApp.FAQitem', related_query_name='grel_%(class)s_for_faq_item') FAQ_items = GenericRelation('GeneralApp.FAQitem', related_query_name='grel_%(class)s_for_faq_item')
class Meta: class Meta:
abstract = True abstract = True

View File

@@ -3,6 +3,8 @@ from .models import *
from django.contrib import admin from django.contrib import admin
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
class Admin_StaticPage(Admin_Trans_BaseModelViewPage): class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
fieldsets = [ fieldsets = [

View File

@@ -0,0 +1,41 @@
# Generated by Django 4.2.2 on 2024-11-15 14:50
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('GeneralApp', '0005_option_name_en_option_name_ru_option_prefix_en_and_more'),
]
operations = [
migrations.CreateModel(
name='MediaItem',
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='Дополнительные данные')),
('object_id', models.PositiveIntegerField()),
('picture', models.ImageField(blank=True, null=True, upload_to='media/', verbose_name='Фото')),
('video', models.FileField(blank=True, null=True, upload_to='media/video/', verbose_name='Видео')),
('comment', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
('comment_ru', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
('comment_en', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
('content_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='contenttypes.contenttype')),
],
options={
'verbose_name': 'Медиа элемент',
'verbose_name_plural': 'Медиа элементы',
},
),
]

View File

@@ -3,6 +3,26 @@ from BaseModels.base_models import BaseModelViewPage, BaseModel
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
# from ckeditor.fields import RichTextField # from ckeditor.fields import RichTextField
from ckeditor_uploader.fields import RichTextUploadingField from ckeditor_uploader.fields import RichTextUploadingField
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
class MediaItem(BaseModel):
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
picture = models.ImageField(upload_to='media/', verbose_name=_('Фото'), null=True, blank=True)
video = models.FileField(upload_to='media/video/', verbose_name=_('Видео'), null=True, blank=True)
comment = models.TextField(verbose_name=_('Комментарий'), null=True, blank=True)
class Meta:
verbose_name = _('Медиа элемент')
verbose_name_plural = _('Медиа элементы')
class StaticPage(BaseModelViewPage): class StaticPage(BaseModelViewPage):
promo_header = models.BooleanField(verbose_name=_('Промо-хэдер'), default=False) promo_header = models.BooleanField(verbose_name=_('Промо-хэдер'), default=False)
@@ -29,9 +49,6 @@ class Option(BaseModel):
class FAQitem(BaseModel): class FAQitem(BaseModel):
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True) content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id') content_object = GenericForeignKey('content_type', 'object_id')

View File

@@ -27,3 +27,9 @@ class FAQitem_TranslationOptions(TranslationOptions):
) )
translator.register(FAQitem, FAQitem_TranslationOptions) translator.register(FAQitem, FAQitem_TranslationOptions)
class MediaItem_TranslationOptions(TranslationOptions):
fields = (
'name', 'comment',
)
translator.register(MediaItem, MediaItem_TranslationOptions)

View File

@@ -1,6 +1,10 @@
from BaseModels.admin_utils import Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline from BaseModels.admin_utils import (
Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline,
AdminImageWidget, get_image_thumb
)
from copy import deepcopy from copy import deepcopy
from django.db import models
from django.utils.translation import gettext as _
class Admin_BaseModel(Admin_BaseIconModel): class Admin_BaseModel(Admin_BaseIconModel):
@@ -86,12 +90,17 @@ class AdminTranslationBase(TranslationAdmin):
'screen': ('modeltranslation/css/tabbed_translation_fields.css',), 'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
} }
from modeltranslation.admin import TranslationGenericStackedInline from modeltranslation.admin import TranslationGenericStackedInline, TranslationGenericTabularInline
class AdminStacked_FAQitem(TranslationGenericStackedInline): class TranslationGenericTabularInlineCustom(TranslationGenericTabularInline):
from GeneralApp.models import FAQitem formfield_overrides = {
model = FAQitem models.ImageField: {'widget': AdminImageWidget},
extra = 0 }
fields = ['order', 'question', 'answer']
def image_thumb(self, obj):
return get_image_thumb(self, obj)
image_thumb.short_description = _('Миниатюра')
image_thumb.allow_tags = True
class Media: class Media:
@@ -105,6 +114,46 @@ class AdminStacked_FAQitem(TranslationGenericStackedInline):
'screen': ('modeltranslation/css/tabbed_translation_fields.css',), 'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
} }
class TranslationGenericStackedInlineCustom(TranslationGenericStackedInline):
formfield_overrides = {
models.ImageField: {'widget': AdminImageWidget},
}
def image_thumb(self, obj):
return get_image_thumb(self, obj)
image_thumb.short_description = _('Миниатюра')
image_thumb.allow_tags = True
class Media:
js = (
'modeltranslation/js/force_jquery.js',
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'modeltranslation/js/tabbed_translation_fields.js',
)
css = {
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}
class AdminStacked_FAQitem(TranslationGenericStackedInlineCustom):
from GeneralApp.models import FAQitem
model = FAQitem
extra = 0
fields = ['order', 'question', 'answer']
class AdminTabular_Mediaitem(TranslationGenericTabularInlineCustom):
from GeneralApp.models import MediaItem
model = MediaItem
extra = 0
fields = ['order', 'video', 'picture']
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):
@@ -129,7 +178,7 @@ class Admin_BaseModelViewPage(Admin_BaseIconModel):
# else: # else:
# return {} # return {}
# #
inlines = [AdminStacked_FAQitem] inlines = [AdminStacked_FAQitem, AdminTabular_Mediaitem]

View File

@@ -132,57 +132,59 @@
<section class="chatterbox"> <section class="chatterbox">
<div class="title">{% translate "Что о нас говорят люди" %}</div> <div class="title">{% translate "Что о нас говорят люди" %}</div>
<div class="chatterbox__slider slick-slider"> <div class="chatterbox__slider slick-slider">
<div class="slick-slide"> {% for media_item in page.get_media_items %}
<div class="chatterbox__slide"> <div class="slick-slide">
<div class="chatterbox__vicon"></div> <div class="chatterbox__slide">
<div class="chatterbox__vicon"></div>
<video src="https://example.com/hexlet.mp4"></video>
<video src="{{ MEDIA_URL }}{{ media_item.video }}"></video>
</div>
</div> </div>
<div class="slick-slide"> </div>
<div class="chatterbox__slide"> {% endfor %}
<div class="chatterbox__vicon"></div> {# <div class="slick-slide">#}
{# <div class="chatterbox__slide">#}
<video src="https://example.com/hexlet.mp4"></video> {# <div class="chatterbox__vicon"></div>#}
{##}
</div> {# <video src="https://example.com/hexlet.mp4"></video>#}
</div> {##}
<div class="slick-slide"> {# </div>#}
<div class="chatterbox__slide"> {# </div>#}
<div class="chatterbox__vicon"></div> {# <div class="slick-slide">#}
{# <div class="chatterbox__slide">#}
<video src="https://example.com/hexlet.mp4"></video> {# <div class="chatterbox__vicon"></div>#}
{##}
</div> {# <video src="https://example.com/hexlet.mp4"></video>#}
</div> {##}
<div class="slick-slide"> {# </div>#}
<div class="chatterbox__slide"> {# </div>#}
<div class="chatterbox__vicon"></div> {# <div class="slick-slide">#}
{# <div class="chatterbox__slide">#}
{# <div class="chatterbox__vicon"></div>#}
</div> {##}
</div> {##}
<div class="slick-slide"> {# </div>#}
<div class="chatterbox__slide"> {# </div>#}
<div class="chatterbox__vicon"></div> {# <div class="slick-slide">#}
{# <div class="chatterbox__slide">#}
{# <div class="chatterbox__vicon"></div>#}
</div> {##}
</div> {##}
<div class="slick-slide"> {# </div>#}
<div class="chatterbox__slide"> {# </div>#}
<div class="chatterbox__vicon"></div> {# <div class="slick-slide">#}
{# <div class="chatterbox__slide">#}
{# <div class="chatterbox__vicon"></div>#}
</div> {##}
</div> {##}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
{# </div>#}
{# </div>#}
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () { $(document).ready(function () {