Skip to content

Commit

Permalink
Merge pull request #806 from Studio-Yandex-Practicum/feature/embed-if…
Browse files Browse the repository at this point in the history
…rame-content-type
  • Loading branch information
AntonZelinsky authored Oct 24, 2024
2 parents 8554337 + 2c76f1b commit edef3d1
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/check_vulnerabilities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ jobs:
inputs: $PRODUCTION $DEVELOP
ignore-vulns: |
GHSA-gw84-84pc-xp82 # requires DRF 3.15 and Django 4
GHSA-rrqc-c2jx-6jgv # requires Django 4
GHSA-jj5c-hhrg-vv5h # there is no update available for xhtml2pdf so far
30 changes: 30 additions & 0 deletions apps/articles/migrations/0015_auto_20241022_2318.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 3.2.25 on 2024-10-22 20:18

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('articles', '0014_project_description_caption'),
]

operations = [
migrations.AlterField(
model_name='blogitemcontent',
name='content_type',
field=models.ForeignKey(limit_choices_to={'app_label': 'content_pages', 'model__in': ('contentunitrichtext', 'embedcode', 'eventsblock', 'imagesblock', 'link', 'personsblock', 'playsblock', 'videosblock')}, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype', verbose_name='Тип объекта'),
),
migrations.AlterField(
model_name='newsitemcontent',
name='content_type',
field=models.ForeignKey(limit_choices_to={'app_label': 'content_pages', 'model__in': ('contentunitrichtext', 'embedcode', 'eventsblock', 'imagesblock', 'link', 'personsblock', 'playsblock', 'videosblock')}, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype', verbose_name='Тип объекта'),
),
migrations.AlterField(
model_name='projectcontent',
name='content_type',
field=models.ForeignKey(limit_choices_to={'app_label': 'content_pages', 'model__in': ('contentunitrichtext', 'embedcode', 'eventsblock', 'imagesblock', 'link', 'personsblock', 'playsblock', 'videosblock')}, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype', verbose_name='Тип объекта'),
),
]
2 changes: 1 addition & 1 deletion apps/content_pages/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
PlaysBlockAdmin,
VideosBlockAdmin,
)
from apps.content_pages.admin.content_items import Link
from apps.content_pages.admin.content_items import EmbedCode, Link
from apps.content_pages.admin.contents import BaseContentInline, BaseContentPageAdmin
3 changes: 2 additions & 1 deletion apps/content_pages/admin/content_items.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.contrib import admin

from apps.content_pages.models import ContentUnitRichText, Link
from apps.content_pages.models import ContentUnitRichText, EmbedCode, Link
from apps.core.mixins import HideOnNavPanelAdminModelMixin


Expand All @@ -10,3 +10,4 @@ class ModelAdminToHide(HideOnNavPanelAdminModelMixin, admin.ModelAdmin):

admin.site.register(ContentUnitRichText, ModelAdminToHide)
admin.site.register(Link, ModelAdminToHide)
admin.site.register(EmbedCode, ModelAdminToHide)
28 changes: 28 additions & 0 deletions apps/content_pages/migrations/0009_embedcode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 3.2.25 on 2024-10-22 20:02

import apps.content_pages.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('content_pages', '0008_alter_extendedperson_options'),
]

operations = [
migrations.CreateModel(
name='EmbedCode',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('title', models.CharField(max_length=250, verbose_name='Заголовок')),
('code', models.TextField(max_length=500, validators=[apps.content_pages.validators.iframe_validator], verbose_name='Тег iframe для встраиваемого содержимого')),
],
options={
'verbose_name': 'Встраиваемое содержимое',
'verbose_name_plural': 'Встраиваемое содержимое',
},
),
]
2 changes: 1 addition & 1 deletion apps/content_pages/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from apps.content_pages.models.content_items import AbstractItemWithTitle, ContentUnitRichText, Link
from apps.content_pages.models.content_items import AbstractItemWithTitle, ContentUnitRichText, EmbedCode, Link
from apps.content_pages.models.contents import AbstractContent, AbstractContentPage

# Prevent isort to rearrange imports and prevent circular imports.
Expand Down
13 changes: 13 additions & 0 deletions apps/content_pages/models/content_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.db import models
from django.utils.html import strip_tags

from apps.content_pages.validators import iframe_validator
from apps.core.models import BaseModel


Expand Down Expand Up @@ -53,3 +54,15 @@ class Link(AbstractItemWithTitle):
class Meta:
verbose_name = "Ссылка с описанием"
verbose_name_plural = "Ссылки с описанием"


class EmbedCode(AbstractItemWithTitle):
"""Embeddable iframe link."""

code = models.TextField(
max_length=500, verbose_name="Тег iframe для встраиваемого содержимого", validators=(iframe_validator,)
)

class Meta:
verbose_name = "Встраиваемое содержимое"
verbose_name_plural = "Встраиваемое содержимое"
1 change: 1 addition & 0 deletions apps/content_pages/models/contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class AbstractContent(models.Model):
"app_label": "content_pages",
"model__in": (
"contentunitrichtext",
"embedcode",
"eventsblock",
"imagesblock",
"link",
Expand Down
1 change: 1 addition & 0 deletions apps/content_pages/serializers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
)
from apps.content_pages.serializers.content_items import (
ContentUnitRichTextSerializer,
EmbdedCodeSerializer,
ExtendedPersonSerializer,
LinkSerializer,
OrderedImageSerializer,
Expand Down
11 changes: 10 additions & 1 deletion apps/content_pages/serializers/content_items.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework import serializers

from apps.content_pages.models import Link, OrderedImage, OrderedVideo
from apps.content_pages.models import EmbedCode, Link, OrderedImage, OrderedVideo
from apps.core.mixins import GetDomainMixin
from apps.core.serializers import PersonRoleSerializer
from apps.library.serializers import AuthorForPlaySerializer as LibraryPlayAuthorSerializer
Expand Down Expand Up @@ -66,6 +66,15 @@ class Meta:
)


class EmbdedCodeSerializer(serializers.ModelSerializer):
class Meta:
model = EmbedCode
fields = (
"title",
"code",
)


class OrderedImageSerializer(serializers.ModelSerializer):
class Meta:
model = OrderedImage
Expand Down
3 changes: 3 additions & 0 deletions apps/content_pages/serializers/contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from apps.content_pages.models import (
ContentUnitRichText,
EmbedCode,
EventsBlock,
ImagesBlock,
Link,
Expand All @@ -12,6 +13,7 @@
)
from apps.content_pages.serializers import (
ContentUnitRichTextSerializer,
EmbdedCodeSerializer,
EventsBlockSerializer,
ImagesBlockSerializer,
LinkSerializer,
Expand All @@ -22,6 +24,7 @@

CONTENT_OBJECT_SERIALIZER_PAIRS = {
ContentUnitRichText: ContentUnitRichTextSerializer,
EmbedCode: EmbdedCodeSerializer,
EventsBlock: EventsBlockSerializer,
ImagesBlock: ImagesBlockSerializer,
Link: LinkSerializer,
Expand Down
7 changes: 7 additions & 0 deletions apps/content_pages/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.core.exceptions import ValidationError


def iframe_validator(code: str):
code = code.strip()
if not (code.startswith("<iframe ") and code.endswith("</iframe>")):
raise ValidationError("Встраиваемое содержимое должно быть заключено в теги <iframe></iframe>")

0 comments on commit edef3d1

Please sign in to comment.