Hi Anssi

With regards to Michal Petrucha's changes, I have the feeling you are 
correct. A solution to this could be to provide a cached property called 
**foreign_keys** that will disguise the actual identity of a ForeignKey. 
Once the Michael's changes are introduced, we could start deprecating the 
cached property and raise a soft warning announcing the change, just like 
we are doing with all the other API calls in Options.
Said this, if developers decide to go with the get_fields() API, then 
unfortunately this will not help.

On Monday, August 18, 2014 12:03:32 PM UTC+2, Anssi Kääriäinen wrote:
>
> On Monday, August 18, 2014 7:45:17 AM UTC+3, Russell Keith-Magee wrote:
>>
>> I understand what you're driving at here, and I've had similar thoughts 
>> over the course of the SoC. The catch is that this makes the API for 
>> get_fields() fairly complicated.
>>
>> If every field fits into one specific type, then get_fields() just 
>> requires a single boolean flag (do I include fields of type X) for each 
>> field type. We can also easily add new field types by adding new booleans 
>> to the API.
>>
>> However, if a field fits into multiple categories, then it's impossible 
>> (or, at least, exceedingly complicated) to make a single call to 
>> get_fields() that will specify all your field requirements. "Get me all 
>> non-virtual data fields" requires "virtual=False, data=True, m2m=False", 
>> but "Get all virtual data fields that represent m2ms" requires 
>> "virtual=True, data=False, m2m=True". You can't pass in both sets of 
>> arguments at the same time, so you either have to make multiple calls to 
>> get_fields(), or you have to invent some sort of query syntax for 
>> get_fields() that allows union queries. 
>>
>> Plus, at the end of the day, get_fields() is abstracted behind highly 
>> cached and optimised properties for key lookups. These properties are 
>> effectively a cached call to get_fields() with a specific set of arguments 
>> - so even if get_fields() doesn't expose a "one category per field" 
>> requirement, the API will require, at some level, names that have clear 
>> (and preferably non-overlapping) membership.
>>
>
> If fields are in multiple categories then users will want to do the full 
> range of set operation on the categories. Encoding that in to the API 
> doesn't sound promising.
>
> I don't think users actually want to get fields based on the suggested 
>>> categorization. I feel we get an easier to use and more flexible API if we 
>>> have higher level categories and allow fields to match multiple categories. 
>>> As a practical example if I want all relation fields, that is going to be 
>>> hard using the suggested API. Getting all relation fields is a more 
>>> realistic use case than getting related virtual objects.
>>>
>>
>> Quite probably true. As a point of interest, the current (as in, 1.6) API 
>> actually doesn't differentiate between category (a) "pure data" and 
>> category (b) "relating data (i.e., FK)" fields - if you ask for "data 
>> fields" you get pure data *and* foreign keys. So, at least as far as 
>> Django's own usage is concerned, you're correct in saying that taxonomy 
>> I've described isn't fully required. 
>>
>> Daniel's survey of internal usage reveals that there are three use cases 
>> for getting a list of fields in Django's internal API:
>>
>>  * Get all data and m2m fields (i.e., categories  a, b, and d). This is 
>> effectively "all fields on *this* model"
>>
>>  * Get all data, m2m, related objects, related m2m, and virtual fields 
>> (i.e., categories a, b, d, f, g, h, i - excluding c and e because Django 
>> doesn't currently have any fields of this type). This is "all fields on 
>> this model, or related to this model"
>>
>>  * Get all m2m fields (i.e., category d)
>>  
>> So - at the very least, we need names to describe those three groups. My 
>> intention with describing a richer taxonomy is to try and give names to 
>> other groupings of interest. 
>>
>> If we want to have all fields to match single and only single category, 
>>> then we need to redefine the categories to make sure ForeignKeys as virtual 
>>> fields are possible, and that more esoteric custom join based fields fit in 
>>> to the categorization.
>>>
>>
>> Agreed - that's why I threw this out there for discussion :-)
>>
>> Properties like "data", "virtual", "external", "related", "relating" - 
>> these are high level concepts describing the way a field manifests. 
>> However, that doesn't mean we need to expose these properties as part of 
>> the formal API.
>>
>> Part of the underlying problem here -- lets say we roll out Django 1.7 
>> with some version of this API, and in 1.8, foreign key fields change to 
>> become virtual. That effectively becomes backwards incompatible for queries 
>> that are sensitive to a "virtual" flag; but it doesn't change the 
>> underlying need to identify that a field is a foreign key. We need to 
>> capture the latter use case, but not necessarily the former.
>>
>  
> Could we go with a minimal API for get_fields()? Instead of having 
> categorization on the get_fields() API, we could provide field flags for 
> the categories. With field flags it is straightforward to filter the return 
> list of get_fields(). As an example, fetching those fields which are 
> relations but which aren't virtual: [f for f in get_fields() if 
> f.relational and not f.virtual]. If this path is taken, then I am not sure 
> how minimal the get_fields() API should be. We likely need flags for at 
> least if the field is defined on local, parent or some remote model.
>
> As for changing ForeignKey to virtual field plus concrete field 
> representation - I just realized this will be backwards incompatible no 
> matter what we do regarding categorization. An all-fields including 
> get_fields() call will return separate author (virtual) and author_id 
> (concrete) fields after the split. I am not sure what we can do about this. 
> It would be very unfortunate if we can't refactor the way ForeignKeys work 
> due to the meta API. Any ideas how we can avoid the backwards compatibility 
> trap?
>
>  - Anssi
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/873e7755-4c0a-4062-a08e-89aa01f927ab%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to