Comments (3)
First, a disclaimer: THIS IS NOT SUPPORTED AT ALL. Do this at your own risk.
It is possible to monkey-patch a Model from a third-party module. However, since the rest of the module was not written with this in mind, this could have weird unintended side-effects, and go horribly wrong in seriously devious and un-obvious ways. However, I couldn't help myself trying to figure out how to do it.
So this seems to be accomplishable by doing these things:
- Import the Model you want to modify somewhere in code that executes at Django startup. For example, in a
models.py
file or theready()
function of an AppConfig. - Get a reference to the field instance you want to modify in
ModelClass._meta.fields
. I only tested with swapping out an AutoField with a HashidAutoField. Swapping an IntegerField with a HashidField should probably also work. Swapping out any other kind of field (like CharField) will probably go horribly wrong. - Swap out the
__class__
of that instance withHashidAutoField
. - Set up the attributes that HashidAutoField expects... the stuff that's normally set in the
__init__()
. You're going to have to do this manually, asAutoField.__init__()
was already called. Hashid*Field expectssalt
,min_length
,alphabet
andallow_int_lookups
to be set in the current version. This could change in the future, and you would need to adjust your monkey-patch. - TEST... and in fact, I wouldn't recommend doing this in production.
from django.conf import settings
from django.contrib.flatpages.models import FlatPage
from hashids import Hashids
from hashid_field import HashidAutoField
field = FlatPage._meta.fields[0]
field.__class__ = HashidAutoField
field.salt = settings.HASHID_FIELD_SALT
field.min_length = 7
field.alphabet = Hashids.ALPHABET
field.allow_int_lookup = True
There definitely seems to be a problem where ./manage.py makemigrations
wants to create a new migration for the field. Which may or may not be bad, but it's wanting to save it in site-packages, which seems bad.
So yeah, not really recommended. Proceed at your own risk.
from django-hashid-field.
Hi!
I want to apply a robust solution in a production environment so this hacky solution could be a big risk with unknown consequences as you say, althought it's another point of view to solve the requirement.
Based on your idea I found a similar approach that could be satisfied with this script utility patch_model.py. I've not testet yet, but it also looks good.
I'm trying to avoid a monkey-patch, but it seems that there not an easy approach like a safe built in django method or pattern so I think that I have three options:
-
Suggest to the maintainer of the app the implementation of an abstract model. This allow to customize the model.
-
Create a fork of the app and include the hash-id attribute to the model. I don't like this option because to include only an attribute I have to include the app to my project and modify it. I think that this have to be avoided. An app have to been developed thinking about its universality and adaptability, so it shoud be easy to do small customizations and modifications from your own app.
-
Apply a tested monkey-patch similar as shown in previous lines.
I'm very grateful with your contribution.
from django-hashid-field.
Yes, no matter what, monkey-patching (which that script still does) is fraught with peril, and can result in some really weird bugs. Further, there may be other parts of the third-party module that would just fail in weird ways because they expect an AutoField
not a HashidAutoField
. Most of the time, it would be fine, but for example if they do a isintance(obj.id, int)
that would fail, as obj.id
would be an instance of Hashid
.
Regarding your point 2, though... you don't need to include it in your project. You can fork the repository, make the modifications and check them in, then have pip install it directly from your fork with something like pip install git+https://github.com/yourusername/your_fork_of_project.git
. Then you can also merge changes in from upstream relatively easy if there are no conflicts. You can even put git+
in your requirements.txt file.
I don't agree that module authors need to make this kind of modification possible (not even sure how in this case) as that can greatly increase the complexity of the code, and/or increase dependencies which can have issues of its own.
Happy coding!
from django-hashid-field.
Related Issues (20)
- Using get_object_or_404 with django-hashid-field HOT 3
- Serializer accepts int parameter although allow int lookup is false HOT 2
- All numeric encoded hashids being treated as natural IDs HOT 7
- AutoField or IntegerField HOT 2
- `enable_hashid_object=False` breaks Django admin? HOT 15
- HashidSerializerCharField returns the non formatted message "'%(value)s' value must be a positive integer or a valid Hashids string." HOT 2
- Hashid value changes after saving instance HOT 3
- Extraction of original integer ID from queryset HOT 1
- Int lookup passed as string finds object on a field with a prefix when allow_int_lookup=False HOT 1
- Add option to encode when reading HOT 2
- field.id doesn't work for templates HOT 1
- DRF-Spectacular schema(openapi) generation warnings HOT 1
- Django Ninja returning int HOT 1
- Using GenericRelation with prefetch_related
- python-hashids is replaced by python-sqids HOT 3
- Add real contains/icontains lookup HOT 1
- hashID issue on django-admin -> quote/unquote HOT 2
- Please upgrade to Django 5.0 HOT 3
- Negative ID HOT 1
- django admin error with version 5.0.2 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-hashid-field.