Q:

Render Wagtail InlinePanel on non-page model, without using snippet?

I have defined two models and linked them as seen below. The Order model should display OrderItems using a Wagtail InlinePanel. How can I get this to work without registering the Order model as a snippet?
from wagtail.admin.edit_handlers import InlinePanel
from wagtail.core.models import Orderable
from wagtail.snippets.models import register_snippet

from modelcluster.fields import (
    ParentalKey,
)
from modelcluster.models import ClusterableModel

@register_snippet
class Order(ClusterableModel):
   panels = [
        InlinePanel("items", label="Order items"),
    ]

    def __str__(self):
        return f"Order {self.id}"

    def get_total_cost(self):
        return sum(item.get_cost() for item in self.items.all())

class OrderItem(Orderable):
    order = ParentalKey(
        Order,
        related_name="items",
        on_delete=models.CASCADE,
        blank=False,
    )
    product = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.PositiveIntegerField(default=1)

    panels = [
        FieldPanel("product"),
        FieldPanel("price"),
        FieldPanel("quantity"),
    ]

A:

Create wagtail_hooks.py in the same app where models.py is found.  Then, in wagtail_hooks.py, do something like this (plenty of extras put in the OrderAdmin class here for you to check out - note that not all of the fields will match yours):
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register

class OrderAdmin(ModelAdmin):
    model = Order
    menu_order = -100
    menu_label = 'Orders'
    menu_icon = 'fa-shopping-cart'
    list_display = ('number', 'customer', 'date_placed', 'total', 'payment_method', 'status')
    list_filter = (OrderStatusFilter, )
    search_fields = ('number', 'customer')
    inspect_view_enabled = True
    inspect_view_fields = ['number', 'status', 'customer', 'shipping_address', 'total', 'subtotal', 'shipping', 'handling', 'tax', 'date_placed', 'notes', 'payment_method', 'payment_card']

modeladmin_register(OrderAdmin)

The above will let you view the Order and it's associated OrderItems without having to declare Order as a snippet.  Reference

