Open
Description
Hi !
Awesome module that works great !
In many cases, it would be nice to have foreign keys represented as str rather than the key itself. It allows for easier analysis of data without requiring one further join step.
It would be nice if there was a way to choose how to export foreign key, maybe even be able to have both representations (in two columns).
Might work on a PR for this if you think it's a good addition.
Cheers,
Olivier
Activity
olivierdalang commentedon Jul 17, 2019
As a reference, here's a quick&dirty implementation of an admin action for this. Worth noting one should make sure to use prefetch_related to avoid very slow performance.
acdha commentedon Jul 17, 2019
Hah, yes — I was just working on a comment suggesting that care should be taken if your
__str__
does anything which triggers lookups.What do you think the syntax should look like — I was wondering whether that's a new function or perhaps something like this:
Current demo:
Ideas:
Use a sentinel class which makes it very easy to tell the desired operation:
… or maybe [overly so?] like the ORM, using the ORM
__
:… or simply do a two-tuple form where the second is a callable which does whatever you want with each object instance:
olivierdalang commentedon Jul 17, 2019
Not sure about the suggestions :
Stringify()
andlambda x: str(x)
are a bit ambiguous, as the syntax lets think that it would convert the field (a primary key) to string. It's not clear we're talking about the related instance.relation____str__
lookup is a bit an abuse of the lookup syntax, as lookups aren't at the same level than model logic (plus that's a lot of underscores).If we want to keep just one function, why not add a parameter, such as
readable_foreign_keys
orrelations_as_text
?In any case, I think it would require two admin actions, as you can't pass arguments to the admin actions.
Contrary to my implementation, I'd suggest to keep the original foreign key in the export, as
__str__
may not be unique and thus prevent from properly using the exported data (e.g. in pivot tables).acdha commentedon Jul 17, 2019
That's definitely just a first pass on naming — maybe it should have been something like
StringifyRelatedField()
in the first case? — but the one I'm thinking after more time is a slight variation on the second:('author', lambda obj: str(obj.author))
as that would both make it clearer which object you're receiving and give the possibility of using other fields if that makes sense, and it gives you the most flexibility whereas a separate class would need variations for whatever other uses people come up with.The main reason I was leaning against having a parameter or a separate function was unintended consequences: if you have more than one related field, you might not want to have all of them do this (e.g. I have a bunch of data which foreign-keys
Language
, which uses the 3 character ISO 639 code which I'd want to export as is) and you might not immediately notice that, say, while performance was fine at first it fell off when someone added another field to the list which wasn't covered by your existing prefetching.This is one of the other things I was wondering about with the syntax above. If I'm thinking about this correctly, it seems like we could have something like this:
olivierdalang commentedon Jul 20, 2019
What about having
author
saving the instance's__str__
andauthor_id
saving the actual key? Those are already accessible from the instance and are quite straightforward.By default, if we don't want a parameter, we could just output both.