[Soc2014] The new Options API

# Main API
Official Wiki page: https://code.djangoproject.com/wiki/new_meta_api

get_fields(m2m, data, related_m2m, related_objects, virtual,
include_parents, include_non_concrete, include_hidden, include_proxy) -> (field, field, ...)

get_field(field_name, m2m, data, related_m2m, related_objects, virtual) -> field

# Cached properties for fast access
fields -> (field, field, ..)
concrete_fields -> (field, field, ...)
local_concrete_fields -> (field, field, ...)
field_names (field_name, field_name, ..)

# Benchmarks
(compared to master)

| Benchmark Name | Control | Experiment | Diff |
| -------------- | ------- | ---------- | ---- |
| url_resolve_flat_i18n_off | 0.3224664569 | 0.3128736854 | 0.0095927715 (2.97% faster) |
| url_resolve_flat | 0.2262115002 | 0.2201457143 | 0.0060657859 (2.68% faster) |
| query_prefetch_related | 0.1185187101 | 0.1131614804 | 0.0053572297 (4.52% faster) |
| query_all | 0.0260368466 | 0.0244047880 | 0.0016320586 (6.27% faster) |
| query_select_related | 0.0590585470 | 0.0582756639 | 0.0007828832 (1.33% faster) |
| query_raw | 0.0150311589 | 0.0149269700 | 0.0001041889 (0.69% faster) |
| query_distinct | 0.0003427148 | 0.0003322124 | 0.0000105023 (3.06% faster) |
| url_resolve | 0.0174066782 | 0.0174011946 | 0.0000054836 (0.03% faster) |
| template_render_simple | 0.0001164556 | 0.0001118183 | 0.0000046372 (3.98% faster) |
| query_delete_related | 0.0003562689 | 0.0003521204 | 0.0000041485 (1.16% faster) |
| form_create | 0.0001154184 | 0.0001116633 | 0.0000037551 (3.25% faster) |
| model_creation | 0.0002620935 | 0.0002592921 | 0.0000028014 (1.07% faster) |
| query_iterator | 0.0002910018 | 0.0002886057 | 0.0000023961 (0.82% faster) |
| form_clean | 0.0000283957 | 0.0000273466 | 0.0000010490 (3.69% faster) |
| url_resolve_nested | 0.0001253605 | 0.0001250029 | 0.0000003576 (0.29% faster) |
| query_delete | 0.0002635837 | 0.0002634764 | 0.0000001073 (0.04% faster) |
| raw_sql | 0.0000513077 | 0.0000515938 | -0.0000002861 (0.56% slower) |
| template_render | 0.0123201489 | 0.0123205304 | -0.0000003815 (0.00% slower) |
| query_none | 0.0001389146 | 0.0001396894 | -0.0000007749 (0.56% slower) |
| query_all_multifield | 0.0442516685 | 0.0442527294 | -0.0000010610 (0.00% slower) |
| multi_value_dict | 0.0001797199 | 0.0001827717 | -0.0000030518 (1.70% slower) |
| query_count | 0.0002346754 | 0.0002384424 | -0.0000037670 (1.61% slower) |
| locale_from_request | 0.0008673787 | 0.0008715868 | -0.0000042081 (0.49% slower) |
| query_exclude | 0.0005133271 | 0.0005178809 | -0.0000045538 (0.89% slower) |
| query_latest | 0.0003925323 | 0.0003977776 | -0.0000052452 (1.34% slower) |
| model_delete | 0.0004462004 | 0.0004532099 | -0.0000070095 (1.57% slower) |
| query_order_by | 0.0003699422 | 0.0003770232 | -0.0000070810 (1.91% slower) |
| query_aggregate | 0.0003185034 | 0.0003258467 | -0.0000073433 (2.31% slower) |
| default_middleware | 0.0004270792 | 0.0004346967 | -0.0000076175 (1.78% slower) |
| query_filter | 0.0004306793 | 0.0004388094 | -0.0000081301 (1.89% slower) |
| query_update | 0.0002333641 | 0.0002430677 | -0.0000097036 (4.16% slower) |
| query_in_bulk | 0.0004901409 | 0.0005011201 | -0.0000109792 (2.24% slower) |
| query_dates | 0.0005465746 | 0.0005576730 | -0.0000110984 (2.03% slower) |
| query_annotate | 0.0006684303 | 0.0006795764 | -0.0000111461 (1.67% slower) |
| query_values | 0.0003065467 | 0.0003197312 | -0.0000131845 (4.30% slower) |
| query_complex_filter | 0.0001333117 | 0.0001471758 | -0.0000138640 (10.40% slower) |
| query_values_list | 0.0002993703 | 0.0003140211 | -0.0000146508 (4.89% slower) |
| template_compilation | 0.0005861163 | 0.0006127477 | -0.0000266314 (4.54% slower) |
| query_get_or_create | 0.0013090134 | 0.0013397813 | -0.0000307679 (2.35% slower) |
| l10n_render | 0.0063407421 | 0.0063731670 | -0.0000324249 (0.51% slower) |
| query_exists | 0.0009287477 | 0.0009753466 | -0.0000465989 (5.02% slower) |
| qs_filter_chaining | 0.0008348227 | 0.0009381652 | -0.0001033425 (12.38% slower) |
| query_raw_deferred | 0.0182870388 | 0.0186469555 | -0.0003599167 (1.97% slower) |
| model_save_new | 0.0142104745 | 0.0145826817 | -0.0003722072 (2.62% slower) |
| model_save_existing | 0.0140855193 | 0.0145498991 | -0.0004643798 (3.30% slower) |
| query_get | 0.0273179531 | 0.0280359745 | -0.0007180214 (2.63% slower) |
Sum of all benchmarks (bigger is better): 0.0212707281
I can see what this functionality is doing (and why it's advantageous to pre-compute), but I'm a little confused why it's on the app registry - especially when the top level keys are Options objects. Why have this cache here, instead of on the Options objects themselves? It can still be cached, but it keeps "all the data about model X" on Model X's options object.