1.8.2 media for landing
This commit is contained in:
@@ -29,12 +29,31 @@ class BaseModel(models.Model):
|
||||
|
||||
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):
|
||||
if self.name:
|
||||
return self.name
|
||||
else:
|
||||
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):
|
||||
if not self.json_data or not node_name in self.json_data:
|
||||
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_items = GenericRelation('GeneralApp.FAQitem', related_query_name='grel_%(class)s_for_faq_item')
|
||||
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ from .models import *
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
|
||||
|
||||
class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
|
||||
|
||||
fieldsets = [
|
||||
|
||||
41
GeneralApp/migrations/0006_mediaitem.py
Normal file
41
GeneralApp/migrations/0006_mediaitem.py
Normal 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': 'Медиа элементы',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -3,6 +3,26 @@ from BaseModels.base_models import BaseModelViewPage, BaseModel
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
# from ckeditor.fields import RichTextField
|
||||
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):
|
||||
promo_header = models.BooleanField(verbose_name=_('Промо-хэдер'), default=False)
|
||||
@@ -29,9 +49,6 @@ class Option(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)
|
||||
object_id = models.PositiveIntegerField()
|
||||
content_object = GenericForeignKey('content_type', 'object_id')
|
||||
|
||||
@@ -27,3 +27,9 @@ class FAQitem_TranslationOptions(TranslationOptions):
|
||||
)
|
||||
translator.register(FAQitem, FAQitem_TranslationOptions)
|
||||
|
||||
class MediaItem_TranslationOptions(TranslationOptions):
|
||||
fields = (
|
||||
'name', 'comment',
|
||||
)
|
||||
translator.register(MediaItem, MediaItem_TranslationOptions)
|
||||
|
||||
|
||||
@@ -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 django.db import models
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
|
||||
class Admin_BaseModel(Admin_BaseIconModel):
|
||||
@@ -86,12 +90,17 @@ class AdminTranslationBase(TranslationAdmin):
|
||||
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
|
||||
}
|
||||
|
||||
from modeltranslation.admin import TranslationGenericStackedInline
|
||||
class AdminStacked_FAQitem(TranslationGenericStackedInline):
|
||||
from GeneralApp.models import FAQitem
|
||||
model = FAQitem
|
||||
extra = 0
|
||||
fields = ['order', 'question', 'answer']
|
||||
from modeltranslation.admin import TranslationGenericStackedInline, TranslationGenericTabularInline
|
||||
class TranslationGenericTabularInlineCustom(TranslationGenericTabularInline):
|
||||
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:
|
||||
|
||||
@@ -105,6 +114,46 @@ class AdminStacked_FAQitem(TranslationGenericStackedInline):
|
||||
'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):
|
||||
pass
|
||||
# def get_fieldsets(self, request, obj=None):
|
||||
@@ -129,7 +178,7 @@ class Admin_BaseModelViewPage(Admin_BaseIconModel):
|
||||
# else:
|
||||
# return {}
|
||||
#
|
||||
inlines = [AdminStacked_FAQitem]
|
||||
inlines = [AdminStacked_FAQitem, AdminTabular_Mediaitem]
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -133,56 +133,58 @@
|
||||
<div class="title">{% translate "Что о нас говорят люди" %}</div>
|
||||
<div class="chatterbox__slider slick-slider">
|
||||
|
||||
<div class="slick-slide">
|
||||
<div class="chatterbox__slide">
|
||||
<div class="chatterbox__vicon"></div>
|
||||
{% for media_item in page.get_media_items %}
|
||||
<div class="slick-slide">
|
||||
<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 class="slick-slide">
|
||||
<div class="chatterbox__slide">
|
||||
<div class="chatterbox__vicon"></div>
|
||||
|
||||
<video src="https://example.com/hexlet.mp4"></video>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="slick-slide">
|
||||
<div class="chatterbox__slide">
|
||||
<div class="chatterbox__vicon"></div>
|
||||
|
||||
<video src="https://example.com/hexlet.mp4"></video>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="slick-slide">
|
||||
<div class="chatterbox__slide">
|
||||
<div class="chatterbox__vicon"></div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="slick-slide">
|
||||
<div class="chatterbox__slide">
|
||||
<div class="chatterbox__vicon"></div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="slick-slide">
|
||||
<div class="chatterbox__slide">
|
||||
<div class="chatterbox__vicon"></div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{# <div class="slick-slide">#}
|
||||
{# <div class="chatterbox__slide">#}
|
||||
{# <div class="chatterbox__vicon"></div>#}
|
||||
{##}
|
||||
{# <video src="https://example.com/hexlet.mp4"></video>#}
|
||||
{##}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# <div class="slick-slide">#}
|
||||
{# <div class="chatterbox__slide">#}
|
||||
{# <div class="chatterbox__vicon"></div>#}
|
||||
{##}
|
||||
{# <video src="https://example.com/hexlet.mp4"></video>#}
|
||||
{##}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# <div class="slick-slide">#}
|
||||
{# <div class="chatterbox__slide">#}
|
||||
{# <div class="chatterbox__vicon"></div>#}
|
||||
{##}
|
||||
{##}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# <div class="slick-slide">#}
|
||||
{# <div class="chatterbox__slide">#}
|
||||
{# <div class="chatterbox__vicon"></div>#}
|
||||
{##}
|
||||
{##}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# <div class="slick-slide">#}
|
||||
{# <div class="chatterbox__slide">#}
|
||||
{# <div class="chatterbox__vicon"></div>#}
|
||||
{##}
|
||||
{##}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
|
||||
Reference in New Issue
Block a user