Solicitud de correo marco de reposo de Django utilizando el modelo Ver Set

Soy nuevo en Django tener antecedentes en Node.js.

Estoy creando una API usando Django, Marco de descanso de Django y PostgreSQL.

# Model for Event.

class Event(models.Model):
    heading = models.TextField()
    event_posted_by = models.ForeignKey(
        CustomUser, on_delete=models.CASCADE, related_name='events_posted', null=True)
    event_construction_site = models.ForeignKey(
        ConstructionSite, on_delete=models.CASCADE, related_name='construction_site_events', null=True)

    def __str__(self):
        return str(self.id)



# Event ViewSet 

class EventViewSet(viewsets.ModelViewSet):
    queryset = Event.objects.all()
    serializer_class = EventSerializer

# Event Serializer

class EventSerializer(serializers.ModelSerializer):
    event_construction_site = ConstructionSiteShortSerializer()
    event_posted_by = CustomUserSerializer()

    class Meta:
        model = Event
        fields = ('id', 'heading',
                  'event_posted_by', 'event_construction_site')

Todo aquí funciona bien y se espera también.

Aquí está la salida de mi GET Request.

   {
        "id": 2,
        "heading": "ABCD",
        "event_posted_by": {
            "id": 1,
            "email": "[email protected]",
            "first_name": "A",
            "last_name": "B",
            "profile_picture": "...",
            "company": {
               "id": 3,
               "name": "Company 3"
             },
        },
        "event_construction_site": {
            "id": 2
        }
    },

Pero ahora cuando se trata de crear un evento esta es la vista django rest framework me muestra.

{
    "heading": "",
    "event_posted_by": {
        "email": "",
        "first_name": "",
        "last_name": "",
        "company": {
            "name": ""
        },
        "profile_picture": "",
        "user_construction_site": []
    },
    "event_construction_site": {}
}

Aquí lo que sé cuando necesito "event_posted_by" en GET Solicita pero no queremos publicar la información del usuario. al crear un evento, igual para información dentro del usuario como user_construction_site aquí el único comportamiento que quiero es enviar al Usuario ID al backend y de alguna manera en mi class EventViewSet(viewsets.ModelViewSet) manejar esta solicitud de correo y mapa "event_posted_by" a los datos de usuario utilizando el usuario ID enviado desde el lado cliente.

Cómo este tipo de problemas son genrally manejados en DRF creando diferentes leer / escribir serailizers?

Pregunta hecha hace 3 años, 4 meses, 27 días - Por techtactician


3 Respuestas:

  • Logré resolver el problema siguiendo la sugerencia de @BriseBalloches en el comentario anterior.

    En resumen actualizado event_posted_by agregando un read_only llave.

    event_posted_by = UserSerializer(read_only=True)

    Respondida el Dec 19, 2020 a las 14:12 - por techsavvypro

    Votos positivos: 0 | Votos negativos: 0

  • Para manejar este tipo de situaciones en Django Rest Framework, puedes utilizar lo que se conoce como "serializadores anidados" para tener diferentes representaciones de tus modelos según el contexto. En este caso, puedes crear un serializador adicional para manejar la representación de la creación de un Evento.

    A continuación, te muestro un ejemplo de cómo puedes lograr esto:

    python
    

    Creación de un serializador especial para la creación de Eventos

    class EventCreationSerializer(serializers.ModelSerializer): event_posted_by = serializers.PrimaryKeyRelatedField(queryset=CustomUser.objects.all(), write_only=True) class Meta: model = Event fields = ('heading', 'event_posted_by', 'event_construction_site') def create(self, validated_data): user_id = validated_data.pop('event_posted_by') custom_user = CustomUser.objects.get(id=user_id) event = Event.objects.create(event_posted_by=custom_user, **validated_data) return event

    Event ViewSet

    class EventViewSet(viewsets.ModelViewSet): queryset = Event.objects.all() serializer_class = EventSerializer serializer_action_classes = { 'create': EventCreationSerializer, 'update': EventSerializer } def get_serializer_class(self): return self.serializer_action_classes.get(self.action, self.serializer_class)

    En este ejemplo, hemos creado un EventCreationSerializer que incluye solo el campo event_posted_by con write_only=True para recibir únicamente el ID del usuario. En el método create, recuperamos el objeto CustomUser correspondiente al ID enviado y creamos un nuevo evento.

    Luego, en el EventViewSet, especificamos diferentes serializadores según la acción que se esté realizando: EventCreationSerializer para la creación de eventos y EventSerializer para cualquier otra acción. Esto se logra a través del diccionario serializer_action_classes y el método get_serializer_class().

    Con esta implementación, al enviar una solicitud de creación de evento que incluya el ID del usuario en el campo event_posted_by, se utilizará el serializador especial EventCreationSerializer para manejar esa solicitud de manera específica.

    Respondida el Dec 20, 2020 a las 14:12 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Creación de serializers de lectura/escritura para manejar solicitudes POST

    Para manejar las solicitudes POST y mapear el ID de usuario enviado a los datos de usuario en tu VistaSet de Django REST Framework, puedes crear diferentes serializers de lectura y escritura:

    Serializer de lectura (GET):

    python
    class EventReadSerializer(serializers.ModelSerializer):
        event_construction_site = ConstructionSiteShortSerializer()
        event_posted_by = CustomUserSerializer()
    
        class Meta:
            model = Event
            fields = ('id', 'heading', 'event_posted_by', 'event_construction_site')
    

    Serializer de escritura (POST):

    python
    class EventWriteSerializer(serializers.ModelSerializer):
        event_posted_by = serializers.IntegerField(write_only=True)
    
        class Meta:
            model = Event
            fields = ('id', 'heading', 'event_posted_by', 'event_construction_site')
    

    VistaSet:

    En tu VistaSet, puedes anular el método get_serializer_class para devolver el serializer adecuado según el método de solicitud:

    python
    class EventViewSet(viewsets.ModelViewSet):
        queryset = Event.objects.all()
    
        def get_serializer_class(self):
            if self.request.method == 'GET':
                return EventReadSerializer
            return EventWriteSerializer
    

    Ejemplo:

    Cuando envíes una solicitud GET, el serializador de lectura se utilizará para devolver los datos del evento, incluidos los detalles del usuario y la obra.

    Cuando envíes una solicitud POST, el serializador de escritura se utilizará para crear un nuevo evento. El ID de usuario enviado se asignará al campo event_posted_by del nuevo evento.

    Nota:

    El campo write_only=True en el serializer de escritura evita que el ID de usuario se incluya en la respuesta de la solicitud POST. Puedes personalizar aún más los serializers para incluir o excluir campos específicos según sea necesario.

    Respondida el Dec 20, 2020 a las 14:17 - por Gemini

    Votos positivos: 0 | Votos negativos: 0