Mohammad Fathi Rahman
Mohammad Fathi Rahman

Reputation: 137

add the full URL in rich text embed image src in Wagtail API V2

Hope you all are doing well. Is there any way to add the full URL in embed image src in API? Here is the API sample

"content": [
                {
                    "type": "full_richtext",
                    "value": "<p data-block-key=\"11dr5\"> Example: The database consists of information about a set of</p><p data-block-key=\"4l7vp\"></p><img alt=\"image-325682-1594637051\" class=\"richtext-image full-width\" height=\"410\" src=\"/media/images/image-325682-1594637051.width-800.jpg\" width=\"728\"><p data-block-key=\"b41bt\"></p><p data-block-key=\"eorjk\"> customers and accounts and the relationship between them) </p>",
                    "id": "f21e7928-f81c-477a-ab42-ba3bc2cd9226"
                }
            ]

how I can add this type of URL like in that src=\"example.com/media/images/imagename\"?

Here is my models.py file.

"""Blog listing and blog detail pages."""
from django.db import models
from modelcluster.fields import ParentalManyToManyField
from django import forms
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel, MultiFieldPanel, InlinePanel

from wagtail.core.fields import StreamField

from wagtail.images.edit_handlers import ImageChooserPanel

from wagtail.core.models import Page
from wagtail.snippets.models import register_snippet

# from . import blocks
from . import blocks
from .blocks import InlineVideoBlock
from rest_framework import fields, serializers

from modelcluster.fields import ParentalKey
from wagtail.api import APIField
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase
from django.shortcuts import render
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
#added by fathi
from rest_framework.fields import Field

@register_snippet
class BlogCategory(models.Model):
    """Blog category for a snippet."""

    name = models.CharField(max_length=255)
    slug = models.SlugField(
        verbose_name="slug",
        allow_unicode=True,
        max_length=255,
        help_text='A slug to identify posts by this category',
    )

    panels = [
        FieldPanel("name"),
        FieldPanel("slug"),
    ]

    class Meta:
        verbose_name = "Blog Category"
        verbose_name_plural = "categories"
        ordering = ["name"]

    def __str__(self):
        return self.name


class CreateNewPage(RoutablePageMixin, Page):
    """Listing page lists all the Blog Detail Pages."""

    # template = "blog/create_new_page.html"

    custom_title = models.CharField(
        max_length=100,
        blank=False,
        null=False,
        help_text='Overwrites the default title',
    )

    content_panels = Page.content_panels + [
        FieldPanel("custom_title"),
    ]

    def get_context(self, request, *args, **kwargs):
        """Adding custom stuff to our context."""
        context = super().get_context(request, *args, **kwargs)
        context["posts"] = AddStory.objects.live().public()
        context["categories"] = BlogCategory.objects.all()

        all_posts = AddStory.objects.live().public().order_by('-first_published_at')
        if request.GET.get('tag', None):
            tags = request.GET.get('tag')
            all_posts = all_posts.filter(tags__slug__in=[tags])

        context["posts"] = all_posts
        return context

    @route(r"^category/(?P<cat_slug>[-\w]*)/$", name="category_view")
    def category_view(self, request, cat_slug):
        """Find blog posts based on a category."""
        context = self.get_context(request)

        try:
            # Look for the blog category by its slug.
            category = BlogCategory.objects.get(slug=cat_slug)
        except Exception:
            # Blog category doesnt exist (ie /blog/category/missing-category/)
            # Redirect to self.url, return a 404.. that's up to you!
            category = None

        if category is None:
            # This is an additional check.
            # If the category is None, do something. Maybe default to a particular category.
            # Or redirect the user to /blog/ ¯\_(ツ)_/¯
            pass

        context["posts"] = AddStory.objects.live().public().filter(categories__in=[category])

        # Note: The below template (latest_posts.html) will need to be adjusted
        return render(request, "blog/latest_posts.html", context)

    @route(r'^latest/?$', name="latest_posts")
    def latest_blog_posts_only_shows_last_5(self, request, *args, **kwargs):
        context = self.get_context(request, *args, **kwargs)
        context["posts"] = context["posts"][:10]
        return render(request, "blog/latest_posts.html", context)


class BlogPageTag(TaggedItemBase):
    content_object = ParentalKey(
        'AddStory',
        related_name='tagged_items',
        on_delete=models.CASCADE
    )


class AddStory(Page):
    """Blog detail page."""

    custom_title = models.CharField(
        max_length=100,
        blank=False,
        null=False,
        help_text='Overwrites the default title',
    )
    blog_image = models.ForeignKey(
        "wagtailimages.Image",
        blank=False,
        null=True,
        related_name="+",
        on_delete=models.SET_NULL,
    )
    categories = ParentalManyToManyField("blog.BlogCategory", blank=True)
    content = StreamField(
        [

            ("full_richtext", blocks.RichtextBlock()),
            ("simple_richtext", blocks.SimpleRichtextBlock()),
            ("Add_video", blocks.VideoRichtextBlock()),
            ('video', InlineVideoBlock()),

        ],
        null=True,
        blank=True,
    )
#exposing custom field in API
    api_fields = [
        # APIField("blog_authors"),
        # Exposed StreamFields
        APIField("blog_image"),
        APIField("content"),
        APIField("categories", serializer=serializers.ListSerializer(child=fields.CharField())),
        APIField("tags"),
    ]
    content2 = StreamField(
        [

            ("full_richtext", blocks.RichtextBlock()),

        ],
        null=True,
        blank=True,
    )

    tags = ClusterTaggableManager(through=BlogPageTag, blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("custom_title"),
        ImageChooserPanel("blog_image"),
        StreamFieldPanel("content"),
        FieldPanel('tags'),
        MultiFieldPanel(
            [
                FieldPanel("categories", widget=forms.CheckboxSelectMultiple),

            ],
            heading="Categories"
        ),

    ]


class VideoBlogPage(AddStory):
    """A video subclassed page."""

    template = "blog/video_blog_page.html"

    youtube_video_id = models.CharField(max_length=30)

    content_panels = Page.content_panels + [
        FieldPanel("custom_title"),
        ImageChooserPanel("blog_image"),
        # MultiFieldPanel(
        #     [
        #         InlinePanel("blog_authors", label="Author", min_num=1, max_num=4)
        #     ],
        #     heading="Author(s)"
        # ),
        MultiFieldPanel(
            [
                FieldPanel("categories", widget=forms.CheckboxSelectMultiple)
            ],
            heading="Categories"
        ),
        FieldPanel("youtube_video_id"),
        StreamFieldPanel("content2"),

    ]

I have searched many places and looked this tutorial but it didn't worked. https://learnwagtail.com/tutorials/headless-cms-serializing-richtext-blocks/

Upvotes: 0

Views: 578

Answers (1)

kirillwolkow
kirillwolkow

Reputation: 13

You can add a serializer. Then in the APIField add this as your serializer.

from rest_framework.fields import Field


class ImageSerializerField(Field):
    def to_representation(self, value):
        return {
            "url": value.file.url,
            "title": value.title,
            "width": value.width,
            "height": value.height,
        }

Upvotes: 0

Related Questions