def get_context_data(self, **kwargs): context = super(SourceView, self).get_context_data(**kwargs) field = ComplexFieldContainer.field_from_str_and_id( context.get('object_type'), context.get('object_id'), context.get('field_name'), context.get('field_id', None)) context['field'] = field return context
def revert_field(request, object_type, object_id, field_name): field = ComplexFieldContainer.field_from_str_and_id( object_type, object_id, field_name ) data = json.loads(request.POST.dict()['revert']) field.revert_field(data['lang'], data['id']) return HttpResponse(status=200)
def get_field_model(cls, field_name): """ Return the ComplexField model corresponding to a field on this model. """ # Get the 0th ID instance, to indicate that we don't want a specific instance # (for more information on these methods, see the source code in the # complex_fields app) container = ComplexFieldContainer.field_from_str_and_id( cls.__name__.lower(), '0', field_name) return container.field_model()
def get_versions(request, object_type, object_id, field_name, field_id=None, lang=get_language()): field = ComplexFieldContainer.field_from_str_and_id( object_type, object_id, field_name, field_id ) if field.translated: versions = field.get_history_for_lang(lang) else: versions = field.get_history() return HttpResponse(json.dumps(versions))
def get_context_data(self, **kwargs): context = super(VersionView, self).get_context_data(**kwargs) field = ComplexFieldContainer.field_from_str_and_id( context.get('object_type'), context.get('object_id'), context.get('field_name'), context.get('field_id', None)) context['field'] = field context['history'] = field.get_history_for_lang() context['langs'] = field.get_langs_in_history() return context
def get_sources(request, object_type, object_id, field_name): field = ComplexFieldContainer.field_from_str_and_id( object_type, object_id, field_name ) sources = field.get_sources() sources_json = { "confidence": field.get_confidence(), "sources": [ { "source": source.source, "id": source.id } for source in sources ] } return HttpResponse(json.dumps(sources_json))
def translate(request, object_type, object_id, field_name): field = ComplexFieldContainer.field_from_str_and_id( object_type, object_id, field_name) if request.method == 'POST': data = json.loads(request.POST.dict()['translation']) try: field.translate(data['value'], data['lang']) return HttpResponse(status=200) except ValidationError as error: return HttpResponseServerError(str(error)) elif request.method == 'GET': translations = field.get_translations() return HttpResponse(json.dumps(translations)) return HttpResponse
def get_sources(request): object_type = request.GET['object_type'] object_id = request.GET['object_id'] field_name = request.GET['field_name'] field = ComplexFieldContainer.field_from_str_and_id( object_type, object_id, field_name) sources = field.get_sources() sources_json = { "confidence": field.get_confidence(), "sources": [], "field_name": field.field_name, } for source in sources: sources_json['sources'].append(extract_source(source)) return HttpResponse(json.dumps(sources_json), content_type='application/json')
def get_sources(request): object_type = request.GET['object_type'] object_id = request.GET['object_id'] field_name = request.GET['field_name'] field = ComplexFieldContainer.field_from_str_and_id( object_type, object_id, field_name ) sources = field.get_sources() sources_json = { "confidence": field.get_confidence(), "sources": [], "field_name": field.field_name, } for source in sources: sources_json['sources'].append(extract_source(source)) return HttpResponse(json.dumps(sources_json), content_type='application/json')
def save(self, commit=True): update_info = {} if not hasattr(self, 'object_ref'): object_ref_fields = [f.column for f in self._meta.model._meta.fields] if 'uuid' in object_ref_fields: self.object_ref = self._meta.model.objects.create(uuid=str(uuid.uuid4())) else: self.object_ref = self._meta.model.objects.create() for field_name, field_model, multiple_values in self.edit_fields: # Somehow when the field is a ComplexFieldListContainer # this method is only ever returning the first one which is OK # unless we are deleting in which case we need all of the associated # fields field = ComplexFieldContainer.field_from_str_and_id( self.object_type, self.object_ref.id, field_name ) source_key = '{}_source'.format(field_name) confidence_key = '{}_confidence'.format(field_name) if field_name in self.update_fields or self.post_data.get(source_key): update_value = self.cleaned_data[field_name] update_key = '{0}_{1}'.format(self._meta.model._meta.object_name, field_model._meta.object_name) confidence = field.get_confidence() if self.post_data.get(confidence_key): confidence = self.post_data[confidence_key][0] update_info[update_key] = { 'confidence': confidence, } if getattr(field_model, 'source_required', False): new_source_ids = self.post_data[source_key] sources = AccessPoint.objects.filter(uuid__in=new_source_ids) update_info[update_key]['sources'] = sources if multiple_values: update_info[update_key]['values'] = update_value new_values = [] for value in update_value: if not isinstance(value, field_model): value, _ = field_model.objects.get_or_create(value=value, object_ref=self.object_ref, lang=get_language()) new_values.append(value) if new_values: update_info[update_key]['values'] = new_values else: update_info[update_key]['value'] = update_value if update_info: self.object_ref.update(update_info) self.object_ref.object_ref_saved() return self.object_ref
def save(self, commit=True): update_info = {} for field_name, field_model, multiple_values in self.edit_fields: # Somehow when the field is a ComplexFieldListContainer # this method is only ever returning the first one which is OK # unless we are deleting in which case we need all of the associated # fields field = ComplexFieldContainer.field_from_str_and_id( self.object_type, self.instance.id, field_name ) if field_name in self.empty_values and multiple_values: field_models = getattr(self.instance, field_name) for field in field_models.get_list(): field_model = field.get_value() field_model.delete() elif field_name in self.empty_values: field_model = field.get_value() if field_model: field_model.delete() source_key = '{}_source'.format(field_name) confidence_key = '{}_confidence'.format(field_name) if field_name in self.update_fields or self.post_data.get(source_key): update_value = self.cleaned_data[field_name] update_key = '{0}_{1}'.format(self.instance._meta.object_name, field_model._meta.object_name) confidence = field.get_confidence() if self.post_data.get(confidence_key): confidence = self.post_data[confidence_key][0] update_info[update_key] = { 'confidence': confidence, } if getattr(field_model, 'source_required', False): new_source_ids = self.post_data[source_key] sources = AccessPoint.objects.filter(uuid__in=new_source_ids) update_info[update_key]['sources'] = sources if multiple_values: update_info[update_key]['values'] = update_value # Sometimes the object that we want the values to normalize # to are not the complex field containers. For instance, we # want the violation perpetrators to normalize to a Person # object for the form, not a ViolationPerpetrator object so # that we can search across all the people, not just the # ones who have committed violations. So, if the values in # update_value are not instances of the field_model, we need # to get or create those and replace the values with the # instances of the field_model so that the validation, etc # works under the hood. new_values = [] for value in update_value: if not isinstance(value, field_model): value, _ = field_model.objects.get_or_create(value=value, object_ref=self.instance, lang=get_language()) new_values.append(value) if new_values: update_info[update_key]['values'] = new_values else: # When we are allowing for new values to be created for # a field where we expect only a single value, we need to # clean up older values so that there is only ever one # related object. This is partially because it's good to be # clean and partially because it sometimes ends up looking # like nothing has changed since Django might always fetch # older items when it's building the objects that get # displayed. existing_values = field_model.objects.filter(object_ref=self.instance) for value in existing_values: if value.value != self.post_data[field_name][0]: value.delete() update_info[update_key]['value'] = update_value if update_info: self.instance.update(update_info) if self.post_data.get('published'): self.instance.published = True else: self.instance.published = False self.instance.save() self.instance.object_ref_saved() return self.instance