django-generic-plus is a python module which provides a Django model field that combines the functionality of GenericForeignKey and FileField into a single field.
It is useful in situations where one wishes to associate metadata with a FileField or ImageField. It is currently used by django-cropduster.
Requirements
Python 3.10+
Django 4.2, 5.0, 5.1, or 5.2
Settings
- GENERIC_PLUS_AUTOPATCH_ADMIN (default True)
django-generic-plus monkeypatches ModelAdmin, InlineModelAdmin, and BaseModelAdmin so that every admin supports GenericForeignFileField. Set this to False to opt out, and add generic_plus.admin.GenericPlusModelAdminMixin to the admin classes whose models have a GenericForeignFileField.
If GENERIC_PLUS_AUTOPATCH_ADMIN is False, any ModelAdmin classes which ought to have GenericPlusModelAdminMixin but do not will be reported by the system check generic_plus.W001.
4.0 upgrade notes
There are no migrations. The changes below are the ones visible from outside the package.
Deleting through a generic relation is scoped to one field. GenericRelatedObjectManager.get_queryset() filters on field_identifier, so instance.<field>_generic_rel.all() returns only that field’s rows and clear() deletes only them. In 3.1.0, clear() deleted every generic row attached to the instance, whatever identifier it carried. That is a data-loss fix, but it was also a working way to drop all of an instance’s attachments at once; code that relied on the old behavior has to clear each field explicitly now. Audit calls to *_generic_rel.clear() before upgrading.
Direct assignment to ``<field>_generic_rel`` raises ``TypeError``. As with Django’s own related managers, the relation cannot be assigned to; assign to the file field or use the manager’s add(), remove() and clear() methods. No working code is affected: in the assignment branch this replaces, a multi-object assignment raised AttributeError on any storage, a single-object assignment raised NotImplementedError on remote storages (it read FieldFile.path), and on local storage it wrote an absolute filesystem path into a column everything else treats as a storage-relative name.
The widget strips ``MEDIA_ROOT`` from the file value it renders. 3.1.0 built the pattern as r'^%s/?' % re.compile(settings.MEDIA_ROOT), interpolating the repr of a compiled pattern, so the substitution matched nothing. The prefix is now removed, and file_value is what the template writes into the hidden input named after the field. A project whose file column stores absolute paths sees both the rendered value and the value posted back change; one storing storage-relative names sees no change.
A custom widget’s attributes are set on the instance. GenericForeignFileField.formfield() assigns parent_admin, request and file_field_name after instantiating the widget. 3.1.0 assigned them to whatever was passed as widget, so a field passing a widget class through formfield(widget=...) had all three land on the class: fields sharing that class read whichever value was written last, and a live WSGIRequest stayed pinned to the class for the worker’s lifetime. A widget subclass that reads any of the three as a class attribute must read them off self.
``get_fieldsets()`` is called fewer times. The patched get_inline_instances() calls it only when one of the admin’s inlines holds a GenericForeignFileField, rather than on every admin on every pass. The inlines returned are unchanged, but an admin whose get_fieldsets() or get_form() has side effects gets fewer calls, in a different order. Relatedly, a duplicate inline is no longer appended for a GenericForeignFileField belonging to another model: the old selection took a symmetric difference against the admin’s existing inline fields, which picked up fields present only in that second set.
``generic_plus.compat`` is removed. compat_rel and compat_rel_to raise ModuleNotFoundError on import; read field.remote_field and field.remote_field.model instead. python-monkey-business is also no longer a dependency, and the replacement decorator uses functools.wraps, so a patched admin method reports __module__ == 'django.contrib.admin.options' rather than 'generic_plus.models'. Code that identified the patch by module name should test for the _generic_plus_patched_original attribute. …
Metadata
Release files for django-generic-plus 4.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_generic_plus-4.0.0.tar.gz | 37.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_generic_plus-4.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 85.2 kB
Release files / django_generic_plus-4.0.0.tar.gz
| Download URL | django_generic_plus-4.0.0.tar.gz |
|---|---|
| Size | 37.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f232b783f093f0d27303cc379caaa0cc41ae06f6dee27fd62a3e7fceaa46b8ba
|
|
BLAKE2b-256 checksum How to use checksums |
9ede97c0e680ad46edcc3a896dca781dd8b1e9ec395701efd3b694ce630edf01
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.5
|
Release files / django_generic_plus-4.0.0-py3-none-any.whl
| Download URL | django_generic_plus-4.0.0-py3-none-any.whl |
|---|---|
| Size | 48.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f17cd473a381bfc8ecd4aaf8a2f45bcd8e8e684fa15d8660032bc69a58bea698
|
|
BLAKE2b-256 checksum How to use checksums |
b4f2c58ff890dbe84d02a51bd59e2890888898ea16756c09f26f56abab5bdf4d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.5
|