1

I'm creating portfolio app. And on the inner page I'd like to give a link to the next portfolio record with it's thumbnail.

Wagtail: Get previous or next sibling — Here is an answer on how to get the url. But it doesn't work for getting other attributes.

If i change 'url' in this method:

def next_portfolio(self):
    if self.get_next_sibling():
        return self.get_next_sibling().url
    else:
        return self.get_siblings().first().url

To get not '.url' but '.thumbnail'

def next_portfolio(self):
    if self.get_next_sibling():
        return self.get_next_sibling().thumbnail
    else:
        return self.get_siblings().first().thumbnail

All I get is an error "'Page' object has no attribute 'thumbnail'". but it have. That's how my model looks like:

class PortfolioItem(Page):
    thumbnail = models.ImageField(upload_to = '', default = None)
    is_feautered = models.BooleanField(default=False)

def next_portfolio_thumb(self):
    if self.get_next_sibling():
        return self.get_next_sibling().thumbnail
    else:
        return self.get_siblings().first()

It should be obvious way to get sibling attribute. Could you please point me on how to do it?

  • 1
    Possible duplicate of [Wagtail unit testing: Adding child pages converts them to base type](https://stackoverflow.com/questions/46529294/wagtail-unit-testing-adding-child-pages-converts-them-to-base-type) – gasman Aug 12 '18 at 22:29
  • @gasman thanks you, but I don't see how it answers my question – Konstantin Bashenko Aug 13 '18 at 08:22
  • @gasman I've read your answer once again carefully to a linked question. And I understand how it could be connected to my question, but on practice I had no luck to get the result I'm looking for. Could you please give me a hint on how to write this function, as I am lost in this tree hierarchy. Thank you. – Konstantin Bashenko Aug 13 '18 at 11:29
  • 1
    To retrieve the `thumbnail` property, you need the specific version of the page object: `self.get_next_sibling().specific.thumbnail` or `self.get_siblings().first().specific.thumbnail`. – gasman Aug 13 '18 at 12:15
  • @gasman Yes, thank you. It took some time for me, but I've got it. Your link kind of answers my question, but in a way someone more experienced would understand. here I've answered my own question in more detailed manner. Hope it will help someone. – Konstantin Bashenko Aug 13 '18 at 12:54

1 Answers1

3

So the answer to this question is following. User named @gasman answered here: Wagtail unit testing: Adding child pages converts them to base type on how to get attributes of hte specific page.

For this we use .specific property.

So first I've opened the shell by:

python manage.py shell

There I've imported models and my model:

>>> from django.db import models
>>> from portfolio import PortfolioItem

After I've emulated current portfolio item, called it and got result of several attributes

>>> page = PortfolioItem.objects.get(title = "Project title1")
>>> page
<PortfolioItem: Project title1>
>>> page.thumbnail
<ImageFieldFile: thumb1.png>

Then I've created instance of "next" where I've called Wagtail's special get_next_sibling() function. As you can see, by itself it wouldn't return specific attributes of the record, but only common one (see the link on top). but after using specific property, you can get all the info you need from the record.

>>> next = page.get_next_sibling()
>>> next
<Page: Project title2>
>>> next.name
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Page' object has no attribute 'name'
>>> next.specific
<PortfolioItem: Project title2>
>>> next.specific.name
'Project name2'

So in my model I've created new function:

def next_port(self):
        if self.get_next_sibling():
            return self.get_next_sibling()
        else:
            return self.get_siblings().first()

And in the template I've used it this way:

<img src="/media/{{ self.next_port.specific.thumbnail }}">

If you have more elegant way of doing the same thing, please let me know.