Question

One of the packages that my Django project uses has a simple admin class that looks like:

class EventUpdateInline(admin.StackedInline):
    model = EventUpdate

class EventAdmin(admin.ModelAdmin):
    form = EventForm
    list_display = ('date_created', 'description', 'status', 'date_updated')
    search_fields = ('description', 'message')
    list_filter = ('services',)
    inlines = [EventUpdateInline]

I've written a custom EventUpdateInline class that I'd like to use. How can I replace the EventUpdateInline with my CustomEventUpdateInline class?

That's the first issue. The second part of the problem is that I'd like to add a custom property to the EventUpdate model so that my CustomEventUpdateInline class can use it.

Where would I put my code to import my CustomEventUpdateInline and replace the old one and old add the custom property to the EventUpdate model?

I'm not sure if this is even possible. Thanks

Was it helpful?

Solution

Edit:

tl;dr: fork and use pip/virtualenv instead - it's a much cleaner, maintainable and sane approach. monkey patching is generally a terrible idea - see linked to SO answer. But sometimes it's the lesser evil.

If you want a quick and dirty monkey patch - https://stackoverflow.com/a/6720998/473285

However usually these days if the project is on github or bitbucket or whatever I just clone it, make my changes and then install my cloned version using pip -e (you are using virtualenv, right?). This is the best approach if you think your changes will be accepted upstream.

The other thing to consider is forwards compatibility. Will your monkey-patching still work after you update the third party package to a later version? Will your changes in git merge cleanly?

Generally I'd use monkey patching under some or all these rare circumstances:

  • you're writing a package for distribution but you need to modify another third-party package to get things working (rare, valid only if the third-party maintainers won't accept a patch)
  • you are doing a relatively straight forward drop-in replacement of classes, methods or functions that will mesh cleanly with the package's internals.
  • the code isn't available or isn't in a form that is easy to work with using pip/virtualenv (rare)
  • you don't think the code will be upgraded or you will ever need to upgrade (unlikely)
  • you're not using pip/virtualenv (bad, but sometimes not possible for legacy, unconventional or badly configured installs).
  • you don't think the upstream maintainers will ever accept your changes or that they will ever be useful to anyone else.

If you're doing more involved changes or something that would be more widely useful then often forking and then trying to get accepted upstream is best. Even if your changes are to facilitate purely internal stuff that will never be used anywhere outside your project virtualenv is by far a better way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top