This sounds like an ideal use for RoutablePageMixin, which allows you to define multiple views for one page, using Django-like URL patterns. In this case, you could define two views, one for the main page (at the URL /images/) and one for a specific object (at the URL /images/123/):
from django.shortcuts import get_object_or_404, render
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
class ProductListingPage(RoutablePageMixin, Page):
@route(r'^$')
def index_view(self, request):
# render the index view
return render(request, 'products/index.html', {
'page': self,
})
@route(r'^(\d+)/$')
def product_view(self, request, product_id):
# render the view for a single item
product = get_object_or_404(Product, id=product_id)
return render(request, 'products/product.html', {
'product': product,
'page': self,
})
If you want to go lower-level, you can try overriding the page's serve method - this is how RoutablePageMixin works internally. Overriding serve is sufficient to support URLs like mysite.com/images?image_id=254 :
class ProductListingPage(Page):
def serve(self, request):
product_id = request.GET.get('image_id', None)
if product_id is None:
return render(request, 'products/index.html', {
'page': self,
})
else:
product = get_object_or_404(Product, id=product_id)
return render(request, 'products/product.html', {
'product': product,
'page': self,
})
To get nicer URLs of the form mysite.com/images/123/, you could override the route method as well.