سؤال

I want to provide a custom view in the admin very similar to changelist_view(), but without the links to the edit form view. Users will be able to select the items in the list and apply actions just like in the change list form but they won't have access to the edit form.

I think the structure in the ModelAdmin class should be like this:

class ProductAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super(ProductAdmin, self).get_urls()
        urls += patterns('',
            (r'^selectlist/$', self.selectlist_view)
        )
        return urls

    def selectlist_view(self):
        return render_to_response(...)

The view to be returned is very similar to ModelAdmin.changelist_view(). What is the best and DRY way to do this?

هل كانت مفيدة؟

المحلول

The following custom ModelAdmin is the best solution I could come up with so far:

class UserModelAdmin(ModelAdmin):
    def get_urls(self):
        urls = super(UserModelAdmin, self).get_urls()
        info = self.model._meta.app_label, self.model._meta.module_name
        select_list_url = patterns('',
            url(r'^selectlist/$', self.selectlist_view, 
                name='%s_%s_select' % info)
        )
        return select_list_url + urls

    def selectlist_view(self, request, extra_context=None):
        temp_list_display_links = self.list_display_links
        self.list_display_links = (None, )
        response = self.changelist_view(request, extra_context)
        self.list_display_links = temp_list_display_links
        return response

نصائح أخرى

I don't really know why, but personally I tend to override (or extend) the change list template for a particular model instead of monkeypatching ModelAdmin.

EDITED:

thanks but i need customization that cannot be done by just overriding the template. for example displaying a different queryset, etc.

In order to display a different queryset you can overrride ModelAdmin.queryset().

also the should not be able to edit the items listed. if i override the template, the user won't see a link to the edit form but he may still access the form and edit it by typing the url if he can guess the url to the form, which would be a security hole.

Why not just remove the edit permission from the users in question? You can override the "add" and "change" views as well:

class SomeModelAdmin(admin.ModelAdmin):
    ...
    def change_view(self, request, object_id, extra_context=None):
        return render_to_response('forbiden_operation.html', dict(op='edit'))
    def ModelAdmin.add_view(self, request, form_url='', extra_context=None):
        return render_to_response('forbiden_operation.html', dict(op='add'))

These are "official" hooks, less likely to break in the future.

Also remember "The Zen of Admin":

At its core, Django’s admin interface is designed for a single activity:

Trusted users editing structured content.

Yes, it’s extremely simple — but that simplicity is based on a whole host of assumptions. The entire philosophy of Django’s admin interface follows directly from these assumptions, so let’s dig into the subtext of this phrase in the sections that follow. “Trusted users …”

The admin interface is designed to be used by people whom you, the developer, trust. This doesn’t just mean “people who have been authenticated”; it means that Django assumes that your content editors can be trusted to do the right thing.

This in turn means that there’s no approval process for editing content — if you trust your users, nobody needs to approve of their edits. Another implication is that the permission system, while powerful, has no support for limiting access on a per-object basis as of this writing. If you trust someone to edit his or her own stories, you trust that user not to edit anyone else’s stories without permission.

“… editing …”

The primary purpose of Django’s admin interface is to let people edit data. This seems obvious at first, but again it has some subtle and powerful repercussions.

For instance, although the admin interface is quite useful for reviewing data (as just described), it’s not designed with that purpose in mind. For example, note the lack of a “can view” permission (see Chapter 12). Django assumes that if people are allowed to view content in the admin interface, they’re also allowed to edit it.

Another more important thing to note is the lack of anything even remotely approaching “workflow.” If a given task requires a series of steps, there’s no support for enforcing that those steps be done in any particular order. Django’s admin interface focuses on editing, not on activities surrounding editing. This avoidance of workflow also stems from the principle of trust: the admin interface’s philosophy is that workflow is a personnel issue, not something to be implemented in code.

Finally, note the lack of aggregation in the admin interface. That is, there’s no support for displaying totals, averages, and so forth. Again, the admin interface is for editing — it’s expected that you’ll write custom views for all the rest.

“… structured content”

As with the rest of Django, the admin interface wants you to work with structured data. Thus, it only supports editing data stored in Django models; for anything else, such as data stored on a filesystem, you’ll need custom views.

Full Stop

It should be clear by now that Django’s admin interface does not try to be all things to all people; instead, we choose to focus tightly on one thing and do that thing extremely well.

When it comes to extending Django’s admin interface, much of that same philosophy holds (note that “extensibility” shows up nowhere in our goals). Because custom Django views can do anything, and because they can easily be visually integrated into the admin interface (as described in the next section), the built-in opportunities for customizing the admin interface are somewhat limited by design.

You should keep in mind that the admin interface is “just an app,” albeit a very complicated one. It doesn’t do anything that any Django developer with sufficient time couldn’t reproduce. It’s entirely possible that in the future someone will develop a different admin interface that is based on a different set of assumptions and thus will behave differently.

Finally, we should point out that, as of this writing, Django developers were working on a new version of the admin interface that allows for much more flexibility in customization. By the time you read this, those new features may have made their way into the bona fide Django distribution. To find out, ask somebody in the Django community whether the “newforms-admin” branch has been integrated.

The admin app has seen a lot of improvement in order to allow more flexibility in customization, but IMHO much of "The Zen of Admin" still holds true.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top