8

i want to pass a variable by URL to another page in django admin. it seems it is not working, i want to pass the variable "/?name=hello", and catch it by request.GET.get["name",""].but the url becomes "/?e=1" after it passed. if i use the default parameter'q', it works, but it will have a conflict. it seems this problem is django-admin only. and i need pass it by url not post... does any one knows how to solve this problem

thanks

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
Grey
  • 1,365
  • 4
  • 23
  • 34

3 Answers3

11

The problem is that the lookup name does not exist when the get_query_set tries to resolve it as a model field. Thus an IncorrectLookupParameters() exception is raised which in turn redirects to the not very helpful "e=1" url. This problem is solved in Django 1.4 with the introduction of custom filterspecs. Until then one possible solution is to dynamically overwrite the ChangeList class returned by your ModelAdmins get_changelist() method.

This solution works on Django 1.3:

class MyModelAdmin(ModelAdmin):

    def get_changelist(self, request, **kwargs):
        changelist_class = super(MyModelAdmin, self).get_changelist(request, 
                                                                 **kwargs)

        class CustomChangeList(changelist_class):
            def __init__(self, request, *args, **kwargs):
                self._name = request.GET.get('name')
                super(CustomChangeList, self).__init__(request, *args, **kwargs)

            def get_query_set(self, *args, **kwargs):
                if self._name:
                    del self.params['name']

                qs = super(CustomChangeList, self).get_query_set(*args, **kwargs)

                if self._name:
                    return qs.filter([FILTER WHAT YOU WANT HERE...])

                return qs


        return CustomChangeList
user3265443
  • 535
  • 1
  • 8
  • 25
Rune Kaagaard
  • 6,643
  • 2
  • 38
  • 29
  • Happens to me in Django 2.0 if there is more than one parameter, e.g. `endpoint/?a=b&c=d` . Works fine with single parameter like `endpoint/?a=b` – SwissNavy Mar 31 '20 at 20:27
1

Can you explain your problem a bit more....why do you want to pass a variable to django admin... also you cant catch GET variable like this... Either use:

request.GET['name'] 

or

request.GET.get('name','')

.get is a instancemethod not a dictionary.

crodjer
  • 13,384
  • 9
  • 38
  • 52
  • i used it request.GET.get('name',''). i want to pass the varible to admin to tell, which reports to show up. q=0 to show the reports who submitted. q=1 to show the rpoets who is been assigned and etc. – Grey Aug 17 '10 at 03:17
  • i can only do that by use parameter q. which q is used by search filed. it was fine. but now i need to use search field. and q will be used for that. so i need to really fix it. – Grey Aug 17 '10 at 03:26
  • u may think why i dont think POST. that reason is that, if there is more reports that one page can show. djang admin use p=1, p=2 to use multiple pages to show all report. but if i dont use GET it will loose track – Grey Aug 17 '10 at 03:27
  • Can you post your models. Do you want to filter the admin site results ? I think what you want is a list_filter = ['field1', 'field2'] option in the admin.py of your model. This will add a filter similar to what you want to achieve through get. – crodjer Aug 20 '10 at 05:03
0

Looks like the question is still unanswered and similar to another question. meesterguyperson posted there a great answer, go check it out.

The solution is to create a "fake filter" that will register a URL parameter with django but will not affect the queryset and admin site appearance.

I adapted meesterguyperson's answer a bit myself and instead of using a blank template to hide the "fake filter", I simply exclude it from the filter pane by returning False from has_output method.

from django.contrib.admin.filters import SimpleListFilter

class KwargPassThroughFilter(SimpleListFilter):
title = ''

# hide from filter pane
def has_output(self):
    return False

# these two function below must be implemented for SimpleListFilter to work
# (any implementation that doesn't affect queryset is fine)
def lookups(self, request, model_admin):
    return (request.GET.get(self.parameter_name), ''),

def queryset(self, request, queryset):
    return queryset

Now, you can subclass this filter and override the parameter_name with the desired name of your param, e.g.

class NameKwargPassThroughFilter(KwargPassThroughFilter):
    parameter_name = 'name'

and append register the filter in the ModelAdmin subclass

class SomethingAdmin(admin.ModelAdmin):
    ...

    list_filter = (
        ...,
        NameKwargPassThroughFilter,
        ...,
    )

    ...

At this point, you can freely use the param in the URL and access it within the scope of SomethingAdmin pages...

Works for Django 3.0+

kopi22
  • 1