def test_get_4_models(self): model1 = FakeContact model2 = FakeOrganisation h_field1 = 'phone' h_field2 = 'url_site' create_fc = FieldsConfig.create create_fc(model1, descriptions=[(h_field1, { FieldsConfig.HIDDEN: True })]) create_fc(model2, descriptions=[(h_field2, { FieldsConfig.HIDDEN: True })]) with self.assertNumQueries(1): fconfigs = FieldsConfig.get_4_models([model1, model2]) self.assertIsInstance(fconfigs, dict) self.assertEqual(2, len(fconfigs)) fc1 = fconfigs.get(model1) self.assertIsInstance(fc1, FieldsConfig) self.assertEqual(model1, fc1.content_type.model_class()) self.assertTrue(fc1.is_fieldname_hidden(h_field1)) self.assertTrue(fconfigs.get(model2).is_fieldname_hidden(h_field2)) with self.assertNumQueries(0): FieldsConfig.get_4_models([model1, model2]) with self.assertNumQueries(0): FieldsConfig.get_4_model(model1)
def _hide_fields(self): fields = self.fields address_mapping = self.address_mapping fconfigs = FieldsConfig.get_4_models((Contact, Organisation, Address)) # TODO: use shipping address if not hidden ? if fconfigs[Contact].is_fieldname_hidden('billing_address'): prefix = HOME_ADDR_PREFIX for form_fname, __ in address_mapping: del fields[prefix + form_fname] is_orga_field_hidden = fconfigs[Organisation].is_fieldname_hidden for fname in [*fields ]: # NB: Cannot mutate the OrderedDict during iteration. # NB: 5 == len('work_') if fname.startswith('work_') and is_orga_field_hidden(fname[5:]): del fields[fname] del fields['update_' + fname] if is_orga_field_hidden('billing_address'): prefix = WORK_ADDR_PREFIX for form_fname, __ in address_mapping: del fields[prefix + form_fname] del fields['update_work_address'] is_addr_field_hidden = fconfigs[Address].is_fieldname_hidden addr_prefixes = self.address_prefixes.values() for form_fname, model_fname in address_mapping: if is_addr_field_hidden(model_fname): for prefix in addr_prefixes: fields.pop(prefix + form_fname, None)
def detailview_display(self, context): from .views import RESPOND_TO_A_CALL_MODELS, Contact, Organisation, Activity number = context[ 'number'] # Ensure that it will crash if we try to load it from a classic load view user = context['user'] filter_viewable = EntityCredentials.filter fconfigs = FieldsConfig.get_4_models(RESPOND_TO_A_CALL_MODELS) all_fields_hidden = True callers = [] for model in RESPOND_TO_A_CALL_MODELS: is_hidden = fconfigs[model].is_field_hidden queries = [ Q(**{field.name: number}) for field in model._meta.fields if isinstance(field, PhoneField) and not is_hidden(field) ] if queries: all_fields_hidden = False callers.extend( filter_viewable( user, model.objects.exclude(is_deleted=True).filter( reduce(or_, queries)))) if all_fields_hidden: raise ConflictError( _('All phone fields are hidden ; please contact your administrator.' )) can_create = user.has_perm_to_create return self._render( self.get_template_context( context, objects=callers, can_create_contact=can_create(Contact), contact_creation_label=Contact.creation_label, can_create_orga=can_create(Organisation), orga_creation_label=Organisation.creation_label, can_create_activity=can_create(Activity), ))
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) models = [*filter(FieldsConfig.is_model_valid, apps.get_models())] # NB: we use <FieldsConfig.get_4_models()> to take advantage of its cache ; # it useful because this constructor can be called several times in a request # because of our wizard (which fill the instance by calling all # previous steps' validation). # Old code: # used_ct_ids = {*FieldsConfig.objects.values_list('content_type', flat=True)} excluded_ct_ids = { # Do not want a choice "creme entity" ('description' can be hidden). ContentType.objects.get_for_model(CremeEntity).id, # Exclude ContentType which already have a configuration *( fc.content_type_id for fc in FieldsConfig.get_4_models(models).values() if not fc._state.adding # <True> means the FieldsConfig is in DB ) } self.ctypes = ctypes = [ ct for ct in map(ContentType.objects.get_for_model, models) if ct.id not in excluded_ct_ids ] if ctypes: self.fields['ctype'].ctypes = ctypes else: # TODO: remove the 'submit' button ? self.fields['ctype'] = fields.CharField( label=_('Related resource'), required=False, widget=Label, initial=_( 'All configurable types of resource are already configured.' ), )