openverse
openverse copied to clipboard
WIP: Unify names of generic relations to media classes
Fixes
Fixes #4553 by @sarayourfriend
Description
This is still WIP because I need to test a bit more thoroughly. So far things appear to work with manual testing, but I haven't run unit tests, and I suspect there are edge cases in the model admins that I have missed.
Heads up through, @dhruvkb, if you want to take a look at the approach I've taken. It's a bit abstract, and I could definitely see wanting to use a more concrete, straightforward, declarative approach that just manually creates the back references onto the media classes.
The approach overrides the metaclass for Django models with one specifically for models related to a media type. The abstract models reference that metaclass, along with a related name, and then subclasses are processed to get assigned to the media class as {related_name}_class
, and the related name from the abstract class is passed down to the Meta
of the final models (which Django doesn't do on its own, only a small set of fields are inherited from Meta
by default).
I initially tried this with __init_subclasses__
but you can kind of see what that results in with the admin models and forms... but a bit more unwieldy because of the related name. It ended up being a lot of specific, fiddly implementation details on each of the related abstract classes, which the metaclass was able to tidy up into a single implementation pretty nicely. Of course, it is a bit magical, so if we want to just, say, hand-maintain a nested dictionary of these relations, kind of like the media_type_config
fixture in the tests (which could be replaced or reduced by some of this work), and prefer that for its straightforwardness (if being slightly more clunky and requiring more manual configuration of relation names) then I can probably be convinced.
My goal was to prevent any SQL migrations, and indeed, sqlmigrate shows the current migration as a complete noop.
Anyway, let me know what you think, Dhruv, if you get a chance to look at this while it's still a draft. Very curious to see what you'll think of this introspective/meta-programming based approach, and whether you can think of an easier way to do it or think a more concrete and less meta approach would be better.
Testing Instructions
TBD.
Checklist
- [ ] My pull request has a descriptive title (not a vague title like
Update index.md
). - [ ] My pull request targets the default branch of the repository (
main
) or a parent feature branch. - [ ] My commit messages follow best practices.
- [ ] My code follows the established code style of the repository.
- [ ] I added or updated tests for the changes I made (if applicable).
- [ ] I added or updated documentation (if applicable).
- [ ] I tried running the project locally and verified that there are no visible errors.
- [ ] I ran the DAG documentation generator (
./ov just catalog/generate-docs
for catalog PRs) or the media properties generator (./ov just catalog/generate-docs media-props
for the catalog or./ov just api/generate-docs
for the API) where applicable.
Developer Certificate of Origin
Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.