1

Can we create a temporary table or views to store the data from 3 or 4 different tables and send a flattened JSON instead of nested JSON to the frontend in Django?

My model is:

class Place(models.Model):
    id = models.IntegerField(primary_key=True)
    location = models.CharField(max_length=100)

    class Meta:
        db_table = 'place'
        managed=False
        
        
class Session(models.Model):
    id = models.IntegerField(primary_key=True)
    place = models.ForeignKey(Place,related_name='session',on_delete=models.CASCADE, null=True)
    start = models.DateField(auto_now=True)
    counts = models.IntegerField()

    class Meta:
        db_table = 'session'
        managed=False


class Animal(models.Model):
    id = models.IntegerField(primary_key=True)
    sess = models.ForeignKey(Session,related_name='details',on_delete=models.CASCADE, null=True)
    type = models.CharField(max_length=100)
    is_active = models.BooleanField()
    length = models.DecimalField(max_digits=6, decimal_places=2)


    class Meta:
        db_table = 'animal'
        managed=False

The flatten output I am trying is:

[
    {
        "location": "Loc 1",
        "session_start": "2021-01-01",
        "session_count": 900,
        "session_details_id": 1,
        "session_details_length_max": "22.00",
        "session_details_length_min": "10.00",
        "session_details_length_avg": "16.43",
        "session_details_length_std": "16.00",
        "session_details_is_active": false,
        "session_details_type": "dog"

    },
        "location": "Loc 1",
        "session_start": "2021-01-02",
        "session_count": 400,
        "session_details_id": 2,
        "session_details_length_max": "19.00",
        "session_details_length_min": "12.00",
        "session_details_length_avg": "15.43",
        "session_details_length_std": "13.00",
        "session_details_is_active": false,
        "session_details_type": "dog"
    }
]

Instead of nested JSON data that I am currently getting The nested JSON data is

[
    {
        "location": "Loc 1",
        "session": [
            {
                "start": "2021-01-01",
                "count": 600,
                "details": [
                    {
                        "id": 1,
                        "length_max": "15.00",
                        "length_min": "10.00",
                        "length_avg": "12.00",
                        "length_std": "13.00",
                        "is_active": false,
                        "type": "dog"
                    }
                ]
            },
            {
                "start": "2021-01-02",
                "count": 400,
                "details": [
                    {
                        "id": 2,
                        "length_max": "19.00",
                        "length_min": "12.00",
                        "length_avg": "15.00",
                        "length_std": "13.00",
                        "is_active": true,
                        "type": "dog"
                    }
                ]
            },
            {
                "start": "2021-01-01",
                "count": 300,
                "details": [
                    {
                        "id": 13,
                        "length_max": "22.00",
                        "length_min": "20.00",
                        "length_avg": "20.00",
                        "length_std": "22.00",
                        "is_active": false,
                        "type": "dog"
                    }
                ]
            }
        ]
    }
]

Like we do in SQL, can we create temporary tables or views in Django to store and flattened?

Shekar
  • 53
  • 5

1 Answers1

0

You don't need extra tables or temporary views for done that.

Here is a SerializerMethodField, I guess what you need. For example in your use case you should create serializer for Animal model because it's related to Session model and Session model related to Place model, simply go from down to up in relations, and get other fields with using SerializerMethodField.

A tiny example:

from rest_framework import serializers


class AnimalSerializer(serializers.ModelSerializer):
    location = serializers.SerializerMethodField()  # You can pass the method argument here, of use the default. If you don't pass this argument your method name should be like `get_<field_name>`, for this field `get_location`
    session_details_type = serializers.SerializerMethodField()
    session_count = serializers.SerializerMethodField()

    def get_location(self, obj):
       return obj.session.place.location

   def get_session_details_type(self, obj):
       return obj.type

   def get_session_count(self, obj):
       # Calculate session count in your way and return it.

You can add more fields like that and achieve what you want.

arif
  • 441
  • 1
  • 6
  • 13
  • Thank you @arif, by doing like this, won't the performance go down? when the data increases and when it is called to the frontend? and in the views, if I need to filter based on location or Date or any other top-level fields it is not possible, any suggestion for that – Shekar Jul 28 '21 at 11:26
  • If I need to post data, this cant be used, because only the columns in the table will be visible right? If there is some good suggestion or steps, please share. – Shekar Jul 28 '21 at 21:03
  • You can override create method of serializer, or create another serializer for posting data – arif Jul 28 '21 at 21:10