view with admin context?

hi guys!

im trying to do something that trully im not sure if its possible…

so, i created a formset (using inlineformset_factory) with two models which works but im having an interesting problem… im not able to load the admin context to it … so the admin add/change forms are kind of weird (they dont have the lateral bar nor the media of the admin site or the title, etc etc… the base template needs all the basic context vars)

is it possible to load somehow the “default” context of the administrator web page in a custom view?

my way to do it might be wrong (clearly lol), not sure, although it works, is there any way around it?

Thank you!

(sorry for my bad english :D)


#admin.py
class modelAdmin(admin.ModelAdmin):

    list_display = ('name', 'code')
    
    ## i override the change url of my form with a view
    def get_urls(self): 
        urls = super().get_urls() 
        urls = [url for url in urls if url.name != 'app_model_add' and url.name != 'app_model_change'] 

        custom_urls = [ 
            path('<path:id>/change/', self.admin_site.admin_view(myview), name='app_model_change'),
        ]
        return custom_urls + urls


        
# views.py 
def myview(request, id=None): 
    #.... code .... 

    if request.method == 'POST':
        #.... code .... which works great when creating or changing a model object


    tabla_form = secondaryModelForm()  
    
    #########
    ### Is it possible here to load somehow the administrator context and then add my custom vars?? 
    ########

    context = {
        #.... code .... 
        # my vars for context and template
        'max_q': 10000,
    }

    return render(request, 'admin/app/mymodeltemplate.html', context)

Yes you can!
This can be achieved through the ModelAdmin instance. So, you have 2 ways that i can think of.

  1. Have your view inside the ModelAdmin class, this way you can do you do it like.
class MyAdmin(admin.ModelAdmin):
  # ...
  def your_view(self, request, id=None):
    context = self.admin_site.each_context(request)

But if you really want your view to not be on the admin.py file you can create:

  1. A ModelAdmin subclass and write a decorator to inject that self.admin_site.each_context context into your view, it may look like this:
from functools import wraps

# custom_admin.py
class CustomModelAdmin(admin.ModelAdmin):
  def admin_view_context_injected(self, view):
    @wraps(view)
    def wrapper(admin, request, *args, **kwargs):
      context = admin.admin_site.each_context(request)
      kwargs["extra_context"] = context
      return view(request, *args, **kwargs)
    return self.admin_site.admin_view(wrapper)

# views.py
def my_view(request, id=None, extra_context=None):
  print("extra_context", extra_context)

# admin.py
# Registering the view on your admin
from custom_admin import CustomModelAdmin
from . import views

class MyAdmin(CustomModelAdmin):
  # ...
  def get_urls(self):
    return super().get_urls() + [path("<path:id>/custom"), self.admin_view_context_injected(views.my_view], name="custom")]
1 Like

Thank you @leandrodesouzadev

not only you made me realize that i could place my view directly in my admin.py but also you helped me solve the issue, ty!

1 Like