Opened 9 years ago

Closed 9 years ago

#24467 closed Bug (fixed)

jQuery error in Django admin site when use "get_prepopulated_fields"

Reported by: Anton Danilchenko Owned by: nobody
Component: contrib.admin Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have Django ModelAdmin for Blog model.

class BlogAdmin(BaseModelAdmin):
    fieldsets = [
        (None, {'fields': ['name', 'description', 'slug']}),
        ('Date information', {'fields': ['date_create', 'date_change']}),
    ]
    # NOTE: this work well 
    # prepopulated_fields = {"slug": ("name",)}

    def get_readonly_fields(self, requets, obj=None):
        """
        Disable edit slug field for object.
        """
        if obj:
            return self.readonly_fields + ('slug',)
        return self.readonly_fields

    def get_prepopulated_fields(self, requets, obj=None):
        """
        Prepopulate slug field only for new object.

        In out case we always return value that I mentioned above for "prepopulated_fields".
        """
        return {"slug": ("name",)}

admin.site.register(Blog, BlogAdmin)

What do I do? I try to show prepopulate field ONLY on create new object page. When we edit this object - I disable option to edit slug field and show it as read-only.

When I use "prepopulated_fields" all work as expected. When I switch to use custom method "get_prepopulated_fields" the jQuery error appear in web browser console:

TypeError: undefined is not a function (evaluating '$(field.id).data('dependency_list', field['dependency_list'])
               .prepopulate(field['dependency_ids'], field.maxLength)')

As I found - the error appear because it's not defined "prepopulate" function:

>>> django.jQuery("#id_slug").prepopulate
undefined

Who knows how to fix this?

Change History (8)

comment:1 by Anton Danilchenko, 9 years ago

I found why it happens. When field "prepopulated_fields" is provided - to HTML page included javascript file "prepopulate.js" and all work as expected. But when we use "get_prepopulated_fields" - this JS file isn't included and we have the error.

I will try to find how it work internally. But maybe someone know how to fix it just now? :-)

comment:2 by Anton Danilchenko, 9 years ago

I found why it happens. I need help from someone who can find workaround for this situation, because to call method "get_prepopulated_fields" we need to pass at least "request" parameter that isn't accessible in "media" dynamic property.

File: "django/contrib/admin/options.py".

-        if self.prepopulated_fields:
+        if self.get_prepopulated_fields(None):
            js.extend(['urlify.js', 'prepopulate%s.js' % extra])

What I can propose - it to refactor "media" property to accept "request" parameter.

OR more easy solution is to delete condition and always include prepopulate.js:

    @property
    def media(self):
        extra = '' if settings.DEBUG else '.min'
        js = [
            'core.js',
            'admin/RelatedObjectLookups.js',
            'jquery%s.js' % extra,
            'jquery.init.js',
            # CHANGED LINES
+           'urlify.js',
+           'prepopulate%s.js' % extra,
        ]
        if self.actions is not None:
            js.append('actions%s.js' % extra)
        return forms.Media(js=[static('admin/js/%s' % url) for url in js])

comment:3 by Simon Charette, 9 years ago

Component: Uncategorizedcontrib.admin
Has patch: set
Keywords: 1.7.5 removed
Patch needs improvement: set
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug
Version: 1.7master

Hi 1st,

This looks like a legitimate bug and unconditionally including propulate.js seems like the correct solution to me.

Please create a pull request against master with your proposed bug fix.

comment:4 by Anton Danilchenko, 9 years ago

Okey, will create Pull Request today. Thanks for a link!

comment:5 by Anton Danilchenko, 9 years ago

comment:6 by Simon Charette, 9 years ago

Triage Stage: AcceptedReady for checkin

comment:7 by Simon Charette, 9 years ago

Patch needs improvement: unset

comment:8 by Tim Graham <timograham@…>, 9 years ago

Resolution: fixed
Status: newclosed

In 28e8c54:

Fixed #24467 -- Removed conditional inclusion of actions.js & prepopulate.js.

The JavaScript may be required when using ModelAdmin.get_actions() or
get_prepopulated_fields(). Always including them is the easiest solution.

Note: See TracTickets for help on using tickets.
Back to Top