- Added link_overlay_enabled, link_overlay_color, link_overlay_opacity to DesignSettings model - Created migration 0008 for new fields - Updated CustomizationPanel with link overlay controls section - Added validation for new overlay settings in serializer - Updated PublicDesignSettingsSerializer to include overlay settings - Applied link overlay to all ExpandableGroup components in public page - Added preview in customization panel for link overlay effect
241 lines
7.9 KiB
Python
241 lines
7.9 KiB
Python
# customization/models.py
|
||
|
||
from django.db import models
|
||
from django.conf import settings
|
||
from django.utils import timezone
|
||
|
||
class DesignSettings(models.Model):
|
||
"""
|
||
Настройки дизайна для публичной страницы пользователя.
|
||
"""
|
||
user = models.OneToOneField(
|
||
settings.AUTH_USER_MODEL,
|
||
on_delete=models.CASCADE,
|
||
related_name='design',
|
||
help_text='Пользователь, которому принадлежат настройки'
|
||
)
|
||
theme_color = models.CharField(
|
||
max_length=7,
|
||
default='#ffffff',
|
||
help_text='Основной цвет темы (hex)'
|
||
)
|
||
background_image = models.ImageField(
|
||
upload_to='customization/',
|
||
null=True,
|
||
blank=True,
|
||
help_text='Фоновое изображение'
|
||
)
|
||
|
||
# Новые поля для дашборда
|
||
dashboard_layout = models.CharField(
|
||
max_length=20,
|
||
choices=[
|
||
('sidebar', 'Боковая панель'),
|
||
('grid', 'Сетка'),
|
||
('list', 'Список'),
|
||
('cards', 'Карточки'),
|
||
('compact', 'Компактный'),
|
||
('masonry', 'Кладка'),
|
||
('timeline', 'Временная линия'),
|
||
('magazine', 'Журнальный'),
|
||
('test-list', 'Тестовый список'),
|
||
],
|
||
default='list',
|
||
help_text='Стиль отображения дашборда'
|
||
)
|
||
groups_default_expanded = models.BooleanField(
|
||
default=True,
|
||
help_text='Развернуты ли группы по умолчанию'
|
||
)
|
||
show_group_icons = models.BooleanField(
|
||
default=True,
|
||
help_text='Показывать иконки групп'
|
||
)
|
||
show_link_icons = models.BooleanField(
|
||
default=True,
|
||
help_text='Показывать иконки ссылок'
|
||
)
|
||
dashboard_background_color = models.CharField(
|
||
max_length=7,
|
||
default='#f8f9fa',
|
||
help_text='Цвет фона дашборда (hex)'
|
||
)
|
||
|
||
font_family = models.CharField(
|
||
max_length=100,
|
||
default='sans-serif',
|
||
help_text='Название шрифта'
|
||
)
|
||
custom_css = models.TextField(
|
||
blank=True,
|
||
help_text='Дополнительный CSS'
|
||
)
|
||
|
||
# Новые поля для цветов текста
|
||
header_text_color = models.CharField(
|
||
max_length=7,
|
||
default='#000000',
|
||
help_text='Цвет заголовков (hex)'
|
||
)
|
||
group_text_color = models.CharField(
|
||
max_length=7,
|
||
default='#333333',
|
||
help_text='Цвет названий групп (hex)'
|
||
)
|
||
link_text_color = models.CharField(
|
||
max_length=7,
|
||
default='#666666',
|
||
help_text='Цвет названий ссылок (hex)'
|
||
)
|
||
|
||
# Поля для настройки обложки
|
||
cover_overlay_enabled = models.BooleanField(
|
||
default=False,
|
||
help_text='Включить цветовое перекрытие обложки'
|
||
)
|
||
cover_overlay_color = models.CharField(
|
||
max_length=7,
|
||
default='#000000',
|
||
help_text='Цвет перекрытия обложки (hex)'
|
||
)
|
||
cover_overlay_opacity = models.FloatField(
|
||
default=0.5,
|
||
help_text='Прозрачность перекрытия (0.0 - 1.0)'
|
||
)
|
||
|
||
# Новые поля для кастомизации групп
|
||
group_overlay_enabled = models.BooleanField(
|
||
default=False,
|
||
help_text='Включить цветовое перекрытие групп'
|
||
)
|
||
group_overlay_color = models.CharField(
|
||
max_length=7,
|
||
default='#000000',
|
||
help_text='Цвет перекрытия групп (hex)'
|
||
)
|
||
group_overlay_opacity = models.FloatField(
|
||
default=0.3,
|
||
help_text='Прозрачность перекрытия групп (0.0 - 1.0)'
|
||
)
|
||
show_groups_title = models.BooleanField(
|
||
default=True,
|
||
help_text='Показывать заголовок "Группы ссылок"'
|
||
)
|
||
group_description_text_color = models.CharField(
|
||
max_length=7,
|
||
default='#666666',
|
||
help_text='Цвет текста описаний групп (hex)'
|
||
)
|
||
|
||
# Новые поля для шрифтов
|
||
body_font_family = models.CharField(
|
||
max_length=100,
|
||
default='',
|
||
blank=True,
|
||
help_text='Шрифт для основного текста'
|
||
)
|
||
heading_font_family = models.CharField(
|
||
max_length=100,
|
||
default='',
|
||
blank=True,
|
||
help_text='Шрифт для заголовков'
|
||
)
|
||
|
||
# ID выбранного шаблона
|
||
template_id = models.CharField(
|
||
max_length=50,
|
||
blank=True,
|
||
null=True,
|
||
help_text='ID выбранного дизайн-шаблона'
|
||
)
|
||
|
||
# Новые поля для цветового оверлея кнопок ссылок
|
||
link_overlay_enabled = models.BooleanField(
|
||
default=False,
|
||
help_text='Включить цветовое перекрытие кнопок ссылок'
|
||
)
|
||
link_overlay_color = models.CharField(
|
||
max_length=7,
|
||
default='#000000',
|
||
help_text='Цвет перекрытия кнопок ссылок (hex)'
|
||
)
|
||
link_overlay_opacity = models.FloatField(
|
||
default=0.2,
|
||
help_text='Прозрачность перекрытия кнопок ссылок (0.0 - 1.0)'
|
||
)
|
||
|
||
updated_at = models.DateTimeField(
|
||
auto_now=True,
|
||
help_text='Дата и время последнего изменения'
|
||
)
|
||
|
||
class Meta:
|
||
verbose_name = 'Настройки дизайна'
|
||
verbose_name_plural = 'Настройки дизайна'
|
||
ordering = ['user']
|
||
unique_together = ('user',)
|
||
|
||
def __str__(self):
|
||
return f"Design for {self.user.username}"
|
||
|
||
def get_background_image_url(self):
|
||
"""
|
||
Возвращает URL фонового изображения.
|
||
"""
|
||
return self.background_image.url if self.background_image else None
|
||
|
||
def get_custom_css(self):
|
||
"""
|
||
Возвращает пользовательский CSS.
|
||
"""
|
||
return self.custom_css or ""
|
||
|
||
def get_design_settings(self):
|
||
"""
|
||
Возвращает словарь с настройками дизайна.
|
||
"""
|
||
return {
|
||
'theme_color': self.theme_color,
|
||
'background_image': self.get_background_image_url(),
|
||
'font_family': self.font_family,
|
||
'custom_css': self.get_custom_css()
|
||
}
|
||
|
||
def save(self, *args, **kwargs):
|
||
"""
|
||
Переопределяем метод save, чтобы автоматически обновлять дату изменения.
|
||
"""
|
||
self.updated_at = timezone.now()
|
||
super().save(*args, **kwargs)
|
||
|
||
def delete(self, *args, **kwargs):
|
||
"""
|
||
Переопределяем метод delete, чтобы удалять связанные изображения.
|
||
"""
|
||
if self.background_image:
|
||
self.background_image.delete(save=False)
|
||
return super().delete(*args, **kwargs)
|
||
|
||
# Вспомогательные методы для доступа к данным пользователя
|
||
|
||
def get_user(self):
|
||
return self.user
|
||
|
||
def get_user_id(self):
|
||
return self.user.id
|
||
|
||
def get_user_username(self):
|
||
return self.user.username
|
||
|
||
def get_user_email(self):
|
||
return self.user.email or "Нет email"
|
||
|
||
def get_user_full_name(self):
|
||
return self.user.get_full_name() or "Нет полного имени"
|
||
|
||
def get_user_bio(self):
|
||
return self.user.bio or "Нет биографии"
|
||
|
||
def get_user_avatar(self):
|
||
return self.user.avatar.url if self.user.avatar else None
|