Rest framework Django

Asked

Viewed 112 times

0

Good evening, I was studying a bit of Rest framework on Jango and I developed a simple Api to consume with Angular went all right however my api I did is limited to

{ 
  [
    {
      "id":1,
      "name":"lima",
      "phone","000000000",
      "email","[email protected]",
      "photo","localhost/members/profile/foto1.jpg"
    },
    {
      "id":2,
      "name":"Carlos",
      "phone","000000000",
      "email","[email protected]",
      "photo","localhost/members/profile/foto2.jpg"
    }
  ]
}

She was limited to this json structure but I wanted to do something more complete and a little more complex kk I’ll give an example here of how I wanted to:

{
   [
      "id": 1,

      "User": {

         "name":"João Vitor",

         "phone":"000000000",

         "email": "[email protected]",
         "configuracoes": {
               "aqui vem algumas configurações setadas pelo usuário 
         }

     },

     "pedidos": [

          {

             "Aqui vem uma lista de pedidos desse usuário que vai chegar através de outra aplicação
          }
     ]
   ]
}

Consuming and manipulating the api using Angular I’m getting the problem right and how I’m going to create this more complex api there. I will leave the model file where I describe my api and then migrate that file.

This is the migrate file 0001

# Generated by Django 3.0.6 on 2020-05-28 14:57

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Member',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=100)),
                ('surname', models.CharField(max_length=100)),
                ('phone', models.CharField(max_length=100)),
                ('email', models.EmailField(max_length=254)),
                ('addres', models.CharField(max_length=100)),
                ('photo', models.ImageField(upload_to='members_profile')),
            ],
        ),
    ]

And this is the model that generated this file:

from django.db import models

# Create your models here.
class Member(models.Model):
    name = models.CharField(max_length=100)
    surname = models.CharField(max_length=100)
    phone = models.CharField(max_length=100)
    email = models.EmailField()
    addres = models.CharField(max_length=100)
    photo = models.ImageField(upload_to='members_profile', blank=True, null=True )

    def __str__(self):
        return f'{self.name} {self.surname}'
  • Hi there. Share the models you are using that you need for your api you will have a new user object and finally configurations? Another thing, eliminate Migrations, having no associated error, it is not relevant to present here, it does not add value to your question. Another thing that got the impression, I may be wrong, is that you developed the client and now you are in the backend, take a look at the concept api-first https://dzone.com/articles/an-api-first-development-approach-1. It is possible to get the api as you want, but the right data structure will have to be created (models).

2 answers

1

The structure you want to return does not correspond to good practices (I believe it is even unviable), as far as I understand it is a list that has a char, an object and another list of sets.

The solution I will inform is a list of objects where this object will have an id, the user object and the order list.

A solution that would facilitate the construction of this structure would be to use the Serializermethodfield, this attribute works for us to define the return of a given field from a method in our serializer.

Follow the serializer for the structure I mentioned:

class UsuarioSerializer(serializers.Serializer):
    name = serializers.CharField()
    phone = serializers.CharField()
    email = serializers.CharField()
    configuracoes = serializers.SerializerMethodField()

    def get_configuracoes(self, objeto):
        configuracoes_usuario = ... #Filter ou alguma forma de associar as configurações ao objeto usuario.

        return configuracoes_usuario # Retorna uma lista ou dicionario de configuracoes

class InterfaceComplexaSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    User = serializers.SerializerMethodField()
    pedidos = serializers.SerializerMethodField()

    def get_User(self, objeto):
        serializer_usuario = UsuarioSerializer(objeto)

        return serializer_usuario.data

    def get_pedidos(self, objeto):
        lista_pedidos = ... #Um filter ou alguma forma de associar os pedidos ao objeto usuario.

        return lista_pedidos


...: meu_serializer = InterfaceComplexaSerializer( 
...:    [ 
...:        objeto_usuario1, 
...:        objeto_usuario2, 
...:        objeto_usuario3 
...:    ],
...:    many=True
...:)

...: print(meu_serializer.data)

Final Result:

>   [
...:   {
...:      "id": 1,
...:      "User": {
...:         "name":"João Vitor",
...:         "phone":"000000000",
...:         "email": "[email protected]",
...:         "configuracoes": {
...:            "config1": "teste",
...:            "config2": "teste2",
...:            "config3": "test3"
...:         }
...:     },
...:     "pedidos": [
...:        "Aqui vem uma lista de pedidos desse usuário que vai chegar através de outra aplicação",
...:        "Outra mensagem",
...:        "Outra mensage2"
...:     ]
...:   }
...:   ...
...:]

Important: The only problem you have to note is that each user object, the methods "get_configuracoes", "get_User" and "get_pedidos" will be executed. That is, if in get_configuracoes you have a search with the filter of the models, and I pass 10 user objects to the "Interfacecomplexaserializer" will be made 10 hits/queries to the database.

0

To have something more complete and complex, as you said, you need to create a Manytomanyfield field in your Model. Example:

from django.db import models
from configuracoes.models import Configuracao

# Create your models here.
class Member(models.Model):
    name = models.CharField(max_length=100)
    surname = models.CharField(max_length=100)
    phone = models.CharField(max_length=100)
    email = models.EmailField()
    addres = models.CharField(max_length=100)
    photo = models.ImageField(upload_to='members_profile', blank=True, null=True )
    configuracoes = models.ManyToManyField(Configuracao)

    def __str__(self):
        return f'{self.name} {self.surname}'

However, this is not enough. You also need to implement the Serializer of the configuration in the Serializer of the user. Example:

from rest_framework.serializers import ModelSerializer
from member.models import Member
from configuracoes.api.serializers import ConfiguracaoSerializer

class MemberSerializer(ModelSerializer):
    configuracoes = ConfiguracaoSerializer(many=True)

    class Meta:
        model = Member
        fields = (
            'id', 'name', 'surname', 'phone', 'email', 'addres', 'photo', 
            'configuracoes'
        )

I hope I’ve helped.

Hugs,

Browser other questions tagged

You are not signed in. Login or sign up in order to post.