能否改写django-file-resubmit模块以适配DBAdminClearableFileInput父类?
Absolutely! There are several clean, flexible approaches to adapt django-file-resubmit to use DBAdminClearableFileInput as the parent class without modifying the module's source code directly. Here are the most practical solutions:
1. Add a Configurable Parent Class via Django Settings (Best Practice)
If you're willing to fork django-file-resubmit or contribute a PR (this is the most maintainable long-term fix), modify the module's widgets.py to pull the parent class from Django settings:
# django-file-resubmit/widgets.py from django.conf import settings from django.forms import ClearableFileInput # Default to Django's built-in class, but allow overriding via settings DEFAULT_PARENT_CLASS = ClearableFileInput PARENT_FILE_INPUT_CLASS = getattr(settings, 'FILE_RESUBMIT_PARENT_INPUT', DEFAULT_PARENT_CLASS) # Handle string paths (e.g., 'dbadmin.widgets.DBAdminClearableFileInput') if isinstance(PARENT_FILE_INPUT_CLASS, str): from django.utils.module_loading import import_string PARENT_FILE_INPUT_CLASS = import_string(PARENT_FILE_INPUT_CLASS) class ResubmitFileInput(PARENT_FILE_INPUT_CLASS): # Keep all existing logic for the class intact ...
Then in your project's settings.py, define the override:
FILE_RESUBMIT_PARENT_INPUT = 'dbadmin.widgets.DBAdminClearableFileInput'
This keeps the module flexible for all users, not just your use case.
2. Monkey-Patch the Class at Runtime
If you can't modify the django-file-resubmit source code, you can dynamically alter the parent class of ResubmitFileInput when your Django app starts. Add this to your app's apps.py:
# your_app/apps.py from django.apps import AppConfig from django_file_resubmit.widgets import ResubmitFileInput from dbadmin.widgets import DBAdminClearableFileInput class YourAppConfig(AppConfig): name = 'your_app' def ready(self): # Replace the parent class with DBAdminClearableFileInput # Preserve any other parent classes if needed (adjust the tuple as required) ResubmitFileInput.__bases__ = (DBAdminClearableFileInput,)
Make sure your app is listed after both django_file_resubmit and your DBAdmin module in INSTALLED_APPS to ensure the classes are loaded before patching.
3. Create a Wrapper Widget Class
Another low-impact option is to create your own widget that inherits from both DBAdminClearableFileInput and ResubmitFileInput, combining their functionality:
# your_app/widgets.py from django_file_resubmit.widgets import ResubmitFileInput from dbadmin.widgets import DBAdminClearableFileInput class DBAdminResubmitFileInput(DBAdminClearableFileInput, ResubmitFileInput): # Resolve any method conflicts here (e.g., if both classes define `render` or `value_from_datadict`) # Example: Prioritize ResubmitFileInput's logic for file resubmission def value_from_datadict(self, data, files, name): return ResubmitFileInput.value_from_datadict(self, data, files, name)
Then use this new class in your forms instead of the original ResubmitFileInput.
Each approach has its tradeoffs: the first is the most scalable, the second avoids modifying external code, and the third gives you full control over the combined behavior.
内容的提问来源于stack exchange,提问作者mirek

