def get_object(self): kwargs = self.kwargs form = get_object_or_404(Form, pk=kwargs.get('form_id')) element_id = kwargs.get('element_id') element_type = kwargs.get('element_type') template = form.template # if the given element id refers to the template's element, # create an answer for it element = elements.get(element_type).objects.get(pk=element_id) if not element.answer_of: # it is the base base template field # element must belong to the same template as forms template if element.field.sub_form.template != template: return Response({'detail': ['invalid element id']}, status=400) # check if there is an answer for this element answer_element = elements.get(element_type).objects.filter( form=form, answer_of=element) if not answer_element.exists(): return elements.get(element_type).objects.create( answer_of=element, form=form) else: return answer_element.first() else: # element itself is the answer return element
class Meta: model = elements.get(element_type) if not simple: fields = abstract_element_fields + [ elements.get(element_type).value_field, 'filters', 'display_title', 'uid', 'display_title_full' ] else: fields = abstract_element_fields + [ elements.get(element_type).value_field, 'uid', ]
class _CreateSerializer(CreateElementWithData): # use char field serializer if multiple values are possible for the given element if elements.get(element_type).value_field == "values": values = CharFieldSerializer(many=True, required=False) class Meta: model = elements.get(element_type) fields = abstract_element_fields + [model.value_field, ] def create(self, validated_data): # if element has multiple values (value filed is "values") # create values objects if elements.get(element_type).value_field == "values": values = validated_data.pop('values', []) obj = super(_CreateSerializer, self).create(validated_data) # create values for value in values: _value = CharField.objects.create(**value) obj.values.add(_value) return obj else: # object is single valued return super(_CreateSerializer, self).create(validated_data)
class SetValueSerializer(serializers.ModelSerializer): if elements.get(element_type).value_field == "values": values = CharFieldSerializer(many=True) class Meta: model = elements.get(element_type) fields = ['pk', model.value_field, ] def update(self, instance, validated_data): values = validated_data.pop('values', []) if self.Meta.model.value_field == 'values': # remove old values and set new values for value in instance.values.all(): value.delete() # add new values for value in values: _value = CharField(**value) _value.save() instance.values.add(_value) return instance else: instance.value = validated_data.get('value') instance.save() return instance
class _Serializer(serializers.ModelSerializer): if elements.get(element_type).value_field == "values": values = CharFieldSerializer(many=True) class Meta: model = elements.get(element_type) fields = ['pk', model.value_field]
def get_elements(self, instance): _elements = get_related_attrs(instance) _elements_data = [] for _element in _elements: _Serializer = get_retrieve_serializer(type(_element).type) _element_data = _Serializer(instance=_element).data if _element.answer_of is None: # this field is not an answer # fined it's answer try: AnswerModel = elements.get(_element.type) _obj = AnswerModel.objects.get( answer_of=_element, form=self.context.get('form')) _new_data = _Serializer(instance=_obj).data _element_data[type(_element).value_field] = _new_data[type( _element).value_field] except AnswerModel.DoesNotExist: pass else: continue _elements_data.append(_element_data) return _elements_data
class _RetrieveSerializer(serializers.ModelSerializer): data = DataSerializer(many=True) if not simple: filters = serializers.SerializerMethodField() if elements.get(element_type).value_field == "values": values = CharFieldSerializer(many=True) class Meta: model = elements.get(element_type) if not simple: fields = abstract_element_fields + [ elements.get(element_type).value_field, 'filters', 'display_title', 'uid', 'display_title_full' ] else: fields = abstract_element_fields + [ elements.get(element_type).value_field, 'uid', ] @staticmethod def get_filters(instance): return instance.filters
def perform_create(self, serializer): data = serializer.save() # add to element element = get_object_or_404(elements.get( self.kwargs.get('element_type')), pk=self.kwargs.get('element_id')) element.data.add(data)
def parse_group(self, group): if not group: return Q() matchType = group['matchType'] val = Q() for rule in group['rules']: if rule['qtype'] == 'group': val = self.operator_table[matchType](val, self.parse_group(rule)) else: # get element model _Element = elements.get(rule['type']) # get value field through related name of the element _related_field_name_value = "%s__%s" % ( _Element.related_name_to_form(), _Element.value_field) # to insure that the retrieved element answer corresponds to the queried element _relate_filed_name_pk = "%s__answer_of__pk" % _Element.related_name_to_form( ) # serialize the query element, this process converts query json to native types # that can be used in object filtering _Serializer = get_raw_converter_serializer(rule['type']) serializer = _Serializer(data=rule) serializer.is_valid(raise_exception=True) _converted_value = serializer.validated_data.get( _Element.value_field) if _Element.value_field == "values": # clear the _converted_value _converted_value = [v['value'] for v in _converted_value] match_Q = reduce( operator.and_, (Q( **{ self.set_filter_on_field( _related_field_name_value, rule['filter']): x }) for x in _converted_value)) else: match_Q = Q( **{ self.set_filter_on_field(_related_field_name_value, rule['filter']): _converted_value, }) _pk_filter = {_relate_filed_name_pk: rule['pk']} val = self.operator_table[matchType](val, match_Q & Q(**_pk_filter)) return val
def create(self, validated_data): # if element has multiple values (value filed is "values") # create values objects if elements.get(element_type).value_field == "values": values = validated_data.pop('values', []) obj = super(_CreateSerializer, self).create(validated_data) # create values for value in values: _value = CharField.objects.create(**value) obj.values.add(_value) return obj else: # object is single valued return super(_CreateSerializer, self).create(validated_data)
def validate_elements_data(self, elements_data): _elements = [] # syntax check element data for element_data in elements_data: # syntax check the incoming element data _element_checks = self.check_attr(element_data, ["type", "pk", "order"]) if _element_checks: raise serializers.ValidationError(_element_checks) # get the element model ElementModel = elements.get(element_data.get('type')) if not ElementModel: raise serializers.ValidationError( "Element with type %s does not exist" % element_data.get('type')) # validate element pk try: el_pk = int(element_data.get('pk')) except (TypeError, ValueError): raise serializers.ValidationError("pk " + element_data.get('pk') + " is not a valid integer") # validate order try: el_order = int(element_data.get('order')) except (TypeError, ValueError): raise serializers.ValidationError("order " + element_data.get('order') + " is not a valid integer") try: _element_obj = ElementModel.objects.get(pk=el_pk) _elements.append({'element': _element_obj, 'order': el_order}) except ElementModel.DoesNotExsit: raise serializers.ValidationError( "Element with type %s and pk %d does not exist" % (element_data.get('type'), element_data.get('pk'))) return _elements
class UpdateSerializer(serializers.ModelSerializer): data = DataSerializer(many=True) if elements.get(element_type).value_field == "values": values = CharFieldSerializer(many=True) class Meta: model = elements.get(element_type) fields = abstract_element_fields + [model.value_field, 'data', ] def update(self, instance, validated_data): _data = validated_data.pop('data', []) _values = validated_data.pop('values', []) with transaction.atomic(): # delete all data for __data in instance.data.all(): __data.delete() # add new data for __data in _data: ___data = Data.objects.create(**__data) instance.data.add(___data) if self.Meta.model.value_field == "values": # delete all values for _value in instance.values.all(): _value.delete() # add values for _value in _values: __value = CharField.objects.create(**_value) instance.values.add(__value) self.Meta.model.objects.filter(pk=instance.pk).update(**validated_data) instance.refresh_from_db() return instance
def get_object(self): return get_object_or_404(elements.get(self.kwargs.get('element_type')), pk=self.kwargs.get('element_id'))
class Meta: model = elements.get(element_type) fields = ['pk', 'condition_element_type', 'condition_element_pk', 'condition_element_value', ]
class Meta: model = elements.get(element_type) fields = abstract_element_fields + [model.value_field, ]
class Meta: model = elements.get(element_type) fields = ['pk', model.value_field]