khashashin
khashashin

Reputation: 1137

Serializing wagtail image chooser

I didn't find information about that. And I'am not sure if it possible to do. So i have following Page models and their relationships:

class TeamRooster(Page):
    team_logo = models.ForeignKey(
        'wagtailimages.Image',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
@register_snippet
class GroupstageTournamentModel(ClusterableModel):
    team_1 = models.ForeignKey(
        TeamRooster,
        null=True, verbose_name='Erste Team',
        on_delete=models.SET_NULL,
        related_name="+",
    )
class GroupstageScreencastRelationship(Orderable, models.Model):
    page = ParentalKey('ScreencastPage',
        related_name='groupstage_screencast_relationship')
    match = models.ForeignKey('GroupstageTournamentModel',
        related_name='match_screen_relationship')
    panels = [
        SnippetChooserPanel('match')
    ]
class ScreencastPage(Page):
    content_panels = Page.content_panels + [
        InlinePanel(
            'groupstage_screencast_relationship', label="Choose Teams"
    ]

    def matches(self):
        matches = [
            n.match for n in self.groupstage_screencast_relationship.all()
        ]
        return matches

    def serve(self, request):
        if request.is_ajax():
            result = [
                {
                    'team_1_logo': match.team_1.team_logo
                }
                for match in self.matches()
            ]
            json_output = json.dumps(result)
            return HttpResponse(json_output)
        else:
            return super(ScreencastPage, self).serve(request)

Is it possible to get a picture from the TeamRooster model with an ajax request? If I try to do this as shown in the code above, then I get an error:
TypeError: Object of type 'Image' is not JSON serializable

Upvotes: 0

Views: 646

Answers (1)

gasman
gasman

Reputation: 25292

The image record probably isn't much use by itself - you need to specify the size it should be displayed at, by generating a rendition. This is the equivalent of using the {% image %} template tag:

http://docs.wagtail.io/en/v1.13.1/advanced_topics/images/renditions.html

Your code would then become something like:

def serve(self, request):
    if request.is_ajax():
        result = []
        for match in self.matches():
            rendition = match.team_1.team_logo.get_rendition('fill-200x200')
            result.append({
                'team_1_logo': rendition.url,
                'team_1_logo_width': rendition.width,
                'team_1_logo_height': rendition.height,
            })

        json_output = json.dumps(result)
        return HttpResponse(json_output)
    else:
        return super(ScreencastPage, self).serve(request)

Upvotes: 1

Related Questions