Q:

Django admin missing Add / Edit buttons when using get_form()

When overriding the get_form() method in a ModelAdmin class, the "Add" and "Edit" (plus sign and pencil) icons do not appear next to any field on the admin page, even though permissions are correct. As soon as I remove the overridden get_form() method, the icons appear. I am using a form factory to render the ModelForm class to do some queryset filtering based on the current user, so I can't use form = <ModelForm> in the admin (the form needs to capture the HttpRequest object).
(Using Django 2.1 and Python 3.6)
admin.py
@admin.register(Reservation)
class ReservationAdmin(admin.ModelAdmin):
    list_display = ('room', 'check_in_date', 'check_out_date', 'guest', 'reserved_by', 'reserved_on')
    inlines = (RoomChangeInline,)

    fieldsets = ( 
    (None, {
        'fields': (
            ('room', 'guest'),
            ('check_in_date', 'check_out_date'),
            ('adults', 'children'),
            ('subtotal', 'taxes', 'deposit'),
            ('reserved_by', 'reserved_on')
        )
    }),)   

    def get_form(self, request, obj=None, **kwargs):
        return reservation_admin_form_factory(request)

forms.py
def reservation_admin_form_factory(request):
    class ReservationAdminForm(forms.ModelForm):
        class Meta: 
            model = Reservation
            exclude = []
            widgets = {
                'check_in_date': forms.DateInput(attrs={'type': 'date'}),
                'check_out_date': forms.DateInput(attrs={'type': 'date'})
            }

        """ I have an __init__() method, but even if I remove it 
        the problem remains, so I am not showing it here. """

    return ReservationAdminForm

A:

To display the Add / Edit buttons on the Django admin change_form page when overriding the ModelAdmin's get_form() you need to wrap the field's widget in a RelatedFieldWidgetWrapper like so:
forms.py
from django import forms
from django.conf import settings
from django.contrib.admin.widgets import RelatedFieldWidgetWrapper
from django.db.models.fields.reverse_related import ManyToOneRel

def reservation_admin_form_factory(request, admin_site):
    class ReservationAdminForm(forms.ModelForm):
        class Meta:
            model = Reservation
            exclude = []

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            rel = ManyToOneRel(Reservation.guest, Guest, 'id')
            self.fields['guest'].widget = RelatedFieldWidgetWrapper(
                 self.fields['guest'].widget, rel, admin_site, 
                     can_change_related=True)

Note the above use of a form factory (reservation_admin_form_factory) to capture the admin_site object, which is needed by RelatedFieldWidgetWrapper.
admin.py*
@admin.register(Reservation)
class ReservationAdmin(admin.ModelAdmin):
    list_display = ('check_in_date', 'check_out_date')

    def get_form(self, request, obj=None, **kwargs):
        self.form = reservation_admin_form_factory(request, admin.site)
        return super().get_form(request, obj, **kwargs)

