Organizational Research By

Surprising Reserch Topic

Question:Django custom admin urls not defined


I am trying to add two URLs to a model admin.

class JobTitleAdmin(admin.ModelAdmin):
    inlines = [OccupationTagInline, ]
    model = JobTitle
    search_fields = ['title',]
    list_filter = ['status',]
    actions =['add_to_job_category', 'move_to_job_category' ]

    def add_to_job_category_view(self, request):

        return render_to_response(
            'admin/job_title/select_job_category.html',
            {
                'action': 'add',
                'featured_occupations': Occupation.objects.filter(featured=True),
                'title_ids': array(request.GET['foo'])
                },
            context_instance=RequestContext(request)
            )

    def get_urls(self):
        urls = super(JobTitleAdmin, self).get_urls()
        custom_urls = patterns('',
            url(r'^add_to_job_category/$', self.admin_site.admin_view(self.add_to_job_category_view), name='admin_jobtitle_add_to_cat',),
            url(r'^move_to_job_category/$', self.admin_site.admin_view(self.move_to_job_category_view), name='admin_jobtitle_move_to_cat',)
    )

        return custom_urls + urls

I've omitted the views code for simplicity.

These 2 patterns are not defined as I get a 404 if I am trying to access them and thet're not listed in django debud 404 page. Yet the method get_urls is properly called (twice actually, not sure why).

What could be wrong?

asked Sep 13, 2013 in Java Interview Questions by rajesh
edited Sep 12, 2013
0 votes
21 views



Related Hot Questions

4 Answers

0 votes
From your code, it would appear that you're attempting to add some action intermediate views to your ModelAdmin class.

This is achieved by putting the function name in the actions attribute. If you're just adding a custom action, there is no need to add a custom url. Your example could be modified like this:

class JobTitleAdmin(admin.ModelAdmin):
    inlines = [OccupationTagInline, ]
    model = JobTitle
    search_fields = ['title',]
    list_filter = ['status',]
    actions =['add_to_job_category', 'move_to_job_category' ]

    def add_to_job_category(self, request, queryset):

        return render_to_response(
            'admin/job_title/select_job_category.html',
            {
                'action': 'add',
                'featured_occupations': Occupation.objects.filter(featured=True),
                'title_ids': array(request.GET['foo'])  # <-- this would probably be changed to use `queryset` function argument
                },
            context_instance=RequestContext(request)
            )
    add_to_job_category.short_description = "Add to job category"

The ModelAdmin class will know how to call your custom function and add the action to the action drop down. The intermediate response view add_to_job_category would need to know how to take input from the action to determine which items were selected.

If you really want to add a custom url, then your get_urls() function appears to be correct. Note that the urls returned by get_urls are with respect to the admin//.

If your app was named myapp and your model JobTitle, then the url to hit your add_to_job_category view would be:

http://some.site/admin/myapp/jobtitle/add_to_job_category/
answered Sep 13, 2013 by rajesh
edited Sep 12, 2013
0 votes
I have done this successfully, but I copied the ModelAdmin.get_urls wrap decorator. Maybe try:

from functools import update_wrapper
class JobTitleAdmin(admin.ModelAdmin):
    inlines = [OccupationTagInline, ]
    model = JobTitle
    search_fields = ['title',]
    list_filter = ['status',]
    actions =['add_to_job_category', 'move_to_job_category' ]

    def add_to_job_category_view(self, request):

        return render_to_response(
            'admin/job_title/select_job_category.html',
            {
                'action': 'add',
                'featured_occupations': Occupation.objects.filter(featured=True),
                'title_ids': array(request.GET['foo'])
                },
            context_instance=RequestContext(request)
            )

    def get_urls(self):
        urls = super(JobTitleAdmin, self).get_urls()

        def wrap(view):
            def wrapper(*args, **kwargs):
                return self.admin_site.admin_view(view)(*args, **kwargs)
            return update_wrapper(wrapper, view)

        custom_urls = patterns('',
            url(r'^add_to_job_category/$',
                 wrap(self.add_to_job_category_view),
                 name='admin_jobtitle_add_to_cat',),
            url(r'^move_to_job_category/$',
answered Sep 13, 2013 by rajesh
edited Sep 12, 2013 by rajesh
0 votes
From your code, it would appear that you're attempting to add some action intermediate views to your ModelAdmin class.

This is achieved by putting the function name in the actions attribute. If you're just adding a custom action, there is no need to add a custom url. Your example could be modified like this:

class JobTitleAdmin(admin.ModelAdmin):
    inlines = [OccupationTagInline, ]
    model = JobTitle
    search_fields = ['title',]
    list_filter = ['status',]
    actions =['add_to_job_category', 'move_to_job_category' ]

    def add_to_job_category(self, request, queryset):

        return render_to_response(
            'admin/job_title/select_job_category.html',
            {
                'action': 'add',
                'featured_occupations': Occupation.objects.filter(featured=True),
                'title_ids': array(request.GET['foo'])  # <-- this would probably be changed to use `queryset` function argument
                },
            context_instance=RequestContext(request)
            )
    add_to_job_category.short_description = "Add to job category"

The ModelAdmin class will know how to call your custom function and add the action to the action drop down. The intermediate response view add_to_job_category would need to know how to take input from the action to determine which items were selected.

If you really want to add a custom url, then your get_urls() function appears to be correct. Note that the urls returned by get_urls are with respect to the admin//.

If your app was named myapp and your model JobTitle, then the url to hit your add_to_job_category view would be:

http://some.site/admin/myapp/jobtitle/add_to_job_category/
answered Sep 13, 2013 by rajesh
edited Sep 12, 2013
0 votes
I have done this successfully, but I copied the ModelAdmin.get_urls wrap decorator. Maybe try:

from functools import update_wrapper
class JobTitleAdmin(admin.ModelAdmin):
    inlines = [OccupationTagInline, ]
    model = JobTitle
    search_fields = ['title',]
    list_filter = ['status',]
    actions =['add_to_job_category', 'move_to_job_category' ]

    def add_to_job_category_view(self, request):

        return render_to_response(
            'admin/job_title/select_job_category.html',
            {
                'action': 'add',
                'featured_occupations': Occupation.objects.filter(featured=True),
                'title_ids': array(request.GET['foo'])
                },
            context_instance=RequestContext(request)
            )

    def get_urls(self):
        urls = super(JobTitleAdmin, self).get_urls()

        def wrap(view):
            def wrapper(*args, **kwargs):
                return self.admin_site.admin_view(view)(*args, **kwargs)
            return update_wrapper(wrapper, view)

        custom_urls = patterns('',
            url(r'^add_to_job_category/$',
                 wrap(self.add_to_job_category_view),
                 name='admin_jobtitle_add_to_cat',),
            url(r'^move_to_job_category/$',
answered Sep 13, 2013 by rajesh
edited Sep 12, 2013 by rajesh

...