Files
links/backend/customization/models.py
Andrey K. Choi d59c1ad42a Add color overlay settings for link buttons
- 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
2025-11-09 13:00:25 +09:00

241 lines
7.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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