开发者

Overriding the admin Media class

Given an admin media class that sets up a rich text editor, like:

class TutorialAdmin(admin.ModelAdmin):

    fields...

    class Media:
        js = ['开发者_如何转开发/paths/to/tinymce.js',]

I would like the ability to selectively override js depending on a field value in the model it references. I've added a "use_editor" boolean to the Tutorial model. The question is, how can I detect whether the current instance has that bool set? I'd like to end up with something like:

class Media:
    if self.use_editor:
        js = ['/path/to/tinymce.js',]
    else:
        js = ''

Ideas? Thanks.


Many thanks to Sam Lai on django-users, I finally have a working solution for this. Turns out to be trickier than expected because you can't directly access field values on the instance from within the Admin class - you need to do it by redefining the form used by the Admin class. In addition, you'll need to use _media rather than "class Media:" to set the media property.

The goal is to detect the current instance value of the use_visual_editor field and turn javascript paths on or off depending on its value (so authors can turn off the visual editor on a per-record basis). Here's the final working solution:

models.py

class Tutorial(models.Model):
    use_visual_editor = models.BooleanField()

forms.py

from django import forms
from tutorials.models import Tutorial

class TutorialAdminForm(forms.ModelForm):
    class Meta:
        model = Tutorial

    def _media(self):
        if self.instance.use_visual_editor == True:
            js = ['/paths/to/javascript',] 
        else:
            js = ['']
        return forms.Media(js=js)

    media = property(_media)

admin.py

from django import forms
....
class TutorialAdmin(admin.ModelAdmin):
    form = TutorialAdminForm

Works perfectly!


An alternative approach, given you're using TinyMCE, is to use an additional JS file that adds a 'mceNoEditor' class to textareas you don't want to convert to rich text.

eg

class fooAdmin(admin.Modeladmin)

  class Media:
        js = ['/path/to/admin-styling.js',
              '/paths/to/tinymce.js',]

In your tinymce.js init, you need to ensure there's a class defined for disabling the editor, such as:

editor_deselector : "mceNoEditor", 

and in the admin-styling.js file have some kind of jQuery call in the document ready handler that finds certain elements and adds that class before TinyMCE is invoked.

Usually you can do this with the 'id_foo' identifier. eg, if you have a model field called additional_notes:

$('textarea#id_additional_notes').addClass('mceNoEditor');

It's possible to use more sophisticated jQuery selectors too, of course.

HTH

Steve

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜