6

Let's say I am using django-tagging application and I decide I want to add a form class to the existing tagging forms. I do not want to patch the form into the existing forms.py since it will be blown out when updated. How do I extend forms.py to include my form class?

I tried adding a "tagging" folder in my app with a forms.py that only included my class, but that breaks the installed app's form classes. (I know it was a long shot, just thought I would give it a try).

Any suggestions on where to look for info on adding a form class to an existing application?

chris
  • 825
  • 2
  • 9
  • 22

2 Answers2

5

The simple answer is, you inherit from the form classes, create your own modifications, and use your modified version.

So, instead of importing from taggit, you would import from your own forms.py

I have done this many times when I want to decorate/enhance an existing app's functionality. The downside is if the the documentation is poor, you have to dig through the source to find out what the call stack is and the inheritance tree for the functionality you want to modify.

The downside of this approach is you cannot modify the contributed application's behavior. So if you want some internal functionality of taggit to use your custom code - this is difficult to implement. However, this is a very rare case.

Should you really want to do that (as I had to do once), you can clone the source and maintain your own copy. Create a branch with your modifications, and make sure you write good tests.

You should then add this code to your django project as its own application; due to Python's lookup rules - it will find your local copy and use it instead of the one from the global site-packages directory.

If the upstream is updated, your burden is then to maintain your copy by making sure tests don't fail when you update/rebase.

Burhan Khalid
  • 152,028
  • 17
  • 215
  • 255
  • In the general case the obvious bit is creating a local django app, i.e. [`startapp`](https://docs.djangoproject.com/en/dev/intro/tutorial01/), inheriting what you want and adding features, but I gather getting django to use your apps code instead of the inherited one depends on the base app. Could you elaborate on the possible ways django might use an app after adding it to `INSTALLED_APPS`, for example via `urls.py`, and how you might hook in your app instead? Is there just one entry point and you have to modify every bit of code down the line to get to the bit you want to change? – jozxyqk Sep 04 '14 at 07:14
  • [django comments](https://docs.djangoproject.com/en/1.4/ref/contrib/comments/custom/) provides `COMMENTS_APP` and expects `get_model`/`get_form` in `__init__.py`, which from my point of view hides the interaction between django and the app. If this wasn't provided is there a standard way to replace a form with my own for example? – jozxyqk Sep 04 '14 at 07:16
2

Jacob Kaplan-Moss, the original developer of Django, answers your question in the abstract (since your question was abstract in the first place) on pages 185 through 203 of his presentation, "Django In the Real World."

However, in order for that advice to apply, the plug-in developer must have written his app in accordance with the guidelines.

Elf Sternberg
  • 15,231
  • 4
  • 52
  • 62
  • Thanks for the info, I am actually surprised that there is not a way to do this out of the box. I guess I will created a new application with a form that uses the models, etc from the installed pluggable app. – chris Nov 08 '10 at 08:15
  • 1
    I'd love some more sources. That presentation is 500 clicks too long. – jozxyqk Aug 31 '14 at 07:38
  • Direct link to slide 185 -> http://www.slideshare.net/jacobian/django-in-the-real-world-1750000/185 – Info-Screen Jan 04 '17 at 19:38