I write a serializer on Django for a model with a lot of nesting and a large number of dependent models (OneToOne).

Basic model:

class Element(models.Model): class Meta: verbose_name = 'Element' verbose_name_plural = 'Elements' name = models.CharField(verbose_name="Name", max_length=255, blank=True, null=True) symbol = models.CharField(verbose_name="Symbol", max_length=255, blank=True, null=True) atomic_number = models.IntegerField(verbose_name="Atomic Number", blank=True, null=True) atomic_weight = models.CharField(verbose_name="Atomic Weight", max_length=255, blank=True, null=True) 

One of the dependent:

 class Group(models.Model): class Meta: verbose_name = 'Group' element = OneToOneField(Element) type = models.CharField(verbose_name='Type', max_length=50, choices=TYPE) value = models.CharField(verbose_name="Value", max_length=255, blank=True, null=True) unit = models.CharField(verbose_name="Unit", max_length=255, blank=True, null=True) 

Accordingly, in the serializer, I need to display this nesting. If the dependent model were alone, it would look like this:

 class ElementSerializer(serializers.ModelSerializer): group = serializers.SerializerMethodField(method_name='get_data') def get_data(self, obj): data = {} data['type'] = obj.group.type data['value'] = obj.group.value data['unit'] = obj.group.unit return data class Meta: model = Element fields = '__all__' 

And gave a similar result:

  { "id": 2, "group": { "type": "classification", "unit": null, "value": "18" }, "name": "Helium", "symbol": "He", "atomic_number": 2, "atomic_weight": "4.002602" }, { "id": 3, "group": { "type": "classification", "unit": null, "value": "1" }, "name": "Hydrogen", "symbol": "H", "atomic_number": 1, "atomic_weight": "1.00794" }, 

And to the question

As you can see, the serializer is a special case. In fact, properties like Group are more than a hundred and it is not good to describe each one with its own method.

As I understand, there must be an abstract method that takes the name of the field and works with it. Fields, so be it, I will form automatically in advance and copy-paste into this file, but without the abstract method everything will be very cumbersome:

 class ElementSerializer(serializers.ModelSerializer): <title> = serializers.SerializerMethodField(method_name='get_data') <title> = serializers.SerializerMethodField(method_name='get_data') <title> = serializers.SerializerMethodField(method_name='get_data') ..... def get_data(self, obj): data = {} data['type'] = obj.<title>.type data['value'] = obj.<title>.value data['unit'] = obj.<title>.unit return data class Meta: model = Element fields = '__all__' 

Can I pull out the field name and use it in the internal method? Or did it turn completely wrong there and for such complex details of the object everything is decided differently?

  • Corrected the name of the question for a better presentation of the essence - while1pass

0