TomRavn
TomRavn

Reputation: 1244

Django Wagtail: get children of page using custom method in django regular view

I am playing with Wagtail 2.6.1 and I got in confusing problem. I need to work with Page model in vanilla Django view. I want to get children of BlogPage, so I made custom method, which should return all children pages. Method works, but only in template view. When I access it in django view, it returns empty queryset. I really don't understand why.

My models.py

class BlogPage(Page):
    template = "blog/blog.html"
    max_count = 1    
    subpage_types = ['blog.BlogPostPage','blog.PostAdvancedPage']        

    promote_panels = Page.promote_panels + [
       FieldPanel('menu_order'),
   ]

    def getChildren(self):
        children = self.get_children().live().all()        
        return children

    def get_context(self, request):
        context = super(BlogPage, self).get_context(request)
        context['categories'] = BlogCategory.objects.order_by('name').all() 
        context['blog_posts'] = self.get_children().live().order_by('-first_published_at').all()            
        return context

    class Meta:
        verbose_name = "Blog"
        verbose_name_plural = "Blogs"

my views.py

from .models import BlogPage

def post_filter(request):
    if request.method == 'POST':      

        posts = BlogPage().getChildren() # this return empty queryset
        print (posts)

but when I render this method in template blog.html it works:

<div class="section py-9">
  {{self.getChildren}}
</div>

it successfully render all children pages in template:

<PageQuerySet [<Page: Lorem Ipsum 01>,<Page: Lorem Ipsum 02>]>

Please note that I am normally using get_context method to render all posts in my template, I just tried render this method (getChildren) in template to check if that's working.

Upvotes: 0

Views: 1052

Answers (1)

gasman
gasman

Reputation: 25227

The line BlogPage().getChildren() means "create a new BlogPage instance in memory, and fetch its children". Naturally, since it's only just been created, it won't have any child pages, and so this returns an empty queryset.

For the post_filter view to do something useful, you'll need to specify an existing BlogPage instance for it to call getChildren on. You haven't mentioned how post_filter is going to be used, so I don't know where this information should come from - but one possibility is to pass it as a parameter in the URL, in which case post_filter will look like this:

def post_filter(request, page_id):
    if request.method == 'POST':
        posts = BlogPage.objects.get(id=page_id).getChildren()
        print (posts)

Upvotes: 1

Related Questions