Changes between Version 14 and Version 15 of new_meta_api


Ignore:
Timestamp:
Jul 11, 2014, 7:33:27 AM (10 years ago)
Author:
pirosb3
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • new_meta_api

    v14 v15  
    200200    *** FieldDoesNotExist: User has no field named 'does_not_exist'
    201201}}}
     202
     203
     204=== The Decision Process
     205
     206Since I started my Summer of Code project, this API has gone through several designs, and has now finalised onto the one shown above.
     207The API has gone through many transformations. Each decision has gone through my mentor, with whom I have weekly meetings (Russell).
     208
     209==== Using bitfields as flags
     210
     211get_field and get_fields were originally designed to work with bits. The main choice for this decision was because there were many options and,
     212in order to avoid providing multiple flags, it would be better to provide bits.
     213The original API for bits is:
     214
     215{{{
     216    DATA = 0b00001
     217    M2M = 0b00010
     218    RELATED_OBJECTS = 0b00100
     219    RELATED_M2M = 0b01000
     220    VIRTUAL = 0b10000
     221
     222    # Aggregates
     223    NON_RELATED_FIELDS = DATA | M2M | VIRTUAL
     224    ALL = RELATED_M2M | RELATED_OBJECTS | M2M | DATA | VIRTUAL
     225
     226    NONE = 0b0000
     227    LOCAL_ONLY = 0b0001
     228    CONCRETE = 0b0010
     229    INCLUDE_HIDDEN = 0b0100
     230    INCLUDE_PROXY = 0b1000
     231
     232    def get_fields(types, opts)
     233}}}
     234
     235There are numerous reasons why we backed away from this design:
     2361) There is always a need to import flags from models/options, this can bring to circular dependencies
     2372) Importing flags all the time can also be a nuinsance
     2382) Importing flags is not Pythonic at all
     239
     240The decision taken was to port 'get_field' and 'get_fields' to flags.
     241A port of the old implementation lies here if you are interested: https://github.com/PirosB3/django/blob/soc2014_meta_refactor_upgrade/django/db/models/options.py
     242
     243==== Removed direct, m2m, model
     244In the previous API, it was a common pattern to return model, direct (bool), m2m (bool). I soon realized that not only
     245these three paramenters can be easily derived from a field_instance, but there were very few places that actually used some of
     246the attributes (there is only 1 place where m2m is used).
     247
     248The decision taken was to drop direct, m2m, model in the return type and only keep field_instance. All the rest will be derived.
     249
     250==== Removed all calls "with_model"
     251As said previously, it is redundant to include any model as this can be derived.
     252
     253==== Removed the need of multiple maps
     254The previous implementation relied on many different cache maps internally. This is somewhat necessary, but tends to increase bug-risk
     255when cache-expiry happens. For this reason, my implementation relies only on 2 cache tables, and I have added a specific function to do
     256cache expiry (called _expire_cache) that will wipe out all memory.
     257The downsides if this aspect is that we cache a bit more naively (there are less layers of caching) but benchmarks show this does not
     258decrease performance.
Back to Top