Last active
August 29, 2015 13:58
-
-
Save scythargon/9949835 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get_chained_select_choices(content_type, depth=1, with_field_types=False): | |
""" Gets field names from the content_type. | |
depth=1 means return any fk or manytomany fields as well | |
TODO: depth>1 is not implemented yet | |
""" | |
if depth > 1: | |
raise Exception("depth should be 0 or 1") | |
# helpers | |
model_klass = content_type.model_class() | |
model_to_fields = defaultdict(list) | |
# dict model -> fields related to that model | |
for fld in (model_klass._meta.fields + model_klass._meta.many_to_many): | |
if fld.rel: | |
model_to_fields[fld.rel.to].append(fld) | |
model_to_fields = dict(model_to_fields) | |
all_fields = sum(model_to_fields.values(), []) | |
# names of fields available on form | |
fields_on_form = set(content_type.config.modelfield_set.values_list('fieldname', flat=True)) | |
def flatelizer(fields): | |
# go thrue every field in model | |
for fld in fields: | |
# if it's foreing key and visible on form | |
if fld.rel and fld.name in fields_on_form: | |
# get all related for that field | |
for subfield in fld.rel.to._meta.fields + fld.rel.to._meta.many_to_many: | |
# if it's related | |
if subfield.rel: | |
# subsubfield.rel.to should pointing to any field on form, it its correct | |
# that pointed field can filter subsubfield by subfield filter | |
for subsubfield in model_to_fields.get(subfield.rel.to, []): | |
# if fld.name != subsubfield.name and subfield: | |
if fld.name != subsubfield.name: | |
yield subsubfield.name, subfield.name, fld.name, | |
tmp = defaultdict(list) | |
for parent, filter_by, fld_name in flatelizer(all_fields): | |
tmp[parent].append([filter_by, fld_name]) | |
choices = [] | |
for parent, subfields in tmp.iteritems(): | |
if len(subfields)==1: | |
choices.append(('{0}__{1}'.format(parent, subfields[0][0], '{0} fld: {1}'.format(parent, subfields[0][1], False, False, False)))) | |
else: | |
for filtered_by, fld_name in subfields: | |
choices.append(('{0}__{1}'.format(parent, filtered_by), '{0} ({1}) fld: {2}'.format(parent, filtered_by, fld_name))) | |
#choices = [(relative_field, relative_field.replace('__', ' → '), '', False, False, ('.field-fieldname select', for_field)) for relative_field, for_field in flatelizer(all_fields)] | |
return tuple(choices) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment