Header Ads Widget

Ticker

6/recent/ticker-posts

Carga de archivos de imagen de Angular 10 y Django 3 con FormData

 A lo largo de este tutorial, veremos cómo podemos implementar la carga de archivos e imágenes en Django 3, Django REST Framework y Angular 10 con un ejemplo paso a paso.

Nuestra aplicación expondrá un /uploadpunto final API REST que acepta solicitudes POST que contienen el archivo de imagen publicado con un multipart/form-datatipo de contenido a través de FormData.

Para la interfaz, usaremos Angular 10 para crear una interfaz simple que le permita al usuario seleccionar un archivo o imagen y subirlo al servidor a través de una solicitud POST usando HttpClientFormData.

En la primera sección, crearemos la aplicación API REST de Django 3 y usaremos un cliente API REST para probar el punto final de carga. A continuación, en la segunda parte, procederemos a crear una aplicación frontend con Angular 10 para cargar la imagen al servidor API REST usando HttpClientFormData.

¡Empecemos!

Prerrequisitos

Para este tutorial, deberá tener algunos requisitos previos, como:

  • Python y pip instalados en su sistema. Usaremos Python 3.7,
  • Familiaridad con Python y Django.
  • Node.js y NPM instalados en su sistema. Estos son requeridos por Angular CLI.
  • Familiaridad con TypeScript.

Creación de un entorno virtual e instalación de Django 3

Si tiene Python y está pipinstalado en su sistema, comencemos creando un nuevo entorno virtual para las dependencias de nuestro proyecto. Abra una nueva terminal, navegue hasta su directorio de trabajo y ejecute el siguiente comando:

$ cd ~/demos
$ python3.7 -m venv .env 

A continuación, active su entorno virtual usando el siguiente comando:

$ source .env/bin/activate

Instalemos ahora Django 3 usando pipEn su terminal ejecute:

$ pip install django

En el momento de escribir este tutorial, este comando se instalará django 3.

Crear un proyecto de Django 3

Ahora, procedamos a crear un proyecto de django 3 usando el siguiente comando:

$ mkdir django-file-upload
$ django-admin startproject fileuploadexample .

Instalación de Django REST Framework

Usaremos el marco Django REST para agregar un punto final de la API REST a nuestra aplicación django 3 que se usará para cargar imágenes desde nuestra interfaz Angular 10:

$ pip install djangorestframework

Abra el fileuploadexample/settings.pyarchivo y agregue
rest_frameworka la INSTALLED_APPSmatriz:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework'
]

Creando una aplicación Django

A continuación, creemos una aplicación django 3 usando los siguientes comandos:

$ cd django-file-upload
$ python manage.py startapp uploadapp

Abra el fileuploadexample/settings.pyarchivo y agregue uploadappa la INSTALLED_APPSmatriz:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'uploadapp'
]

También debe agregar la siguiente configuración para especificar dónde se guardarán los archivos de imagen cargados y desde qué URL se pueden publicar:

MEDIA_URL =  '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

Agregar un modelo de base de datos

A continuación, abra el uploadapp/models.pyarchivo y agregue el siguiente modelo:

from django.db import models
from .models import File

class File(models.Model):
    file = models.FileField(blank=False, null=False)
    def __str__(self):
        return self.file.name

Nuestro modelo tiene solo un nombre filede campo de tipo FileFieldTambién puede usar ImageFieldsi solo necesita admitir la carga de imágenes en su servidor de API REST.

Nota : tenga en cuenta que los archivos / imágenes cargados FileFieldImageFieldno se guardan en la base de datos, sino en el sistema de archivos de su servidor. En la base de datos, el campo está representado por un que VARCHARcontiene la referencia al archivo.

Es obligatorio para MEDIA_URLMEDIA_ROOTen su archivo de configuración.

Consulte Cómo usar Django ImageField y por qué usarlo.

Agregar el serializador de modelos

Cree un serializers.pyarchivo uploadappy agregue el siguiente código:

from rest_framework importserializers

class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model = File
        fields = "__all__"

Agregar la vista API

A continuación, agreguemos la vista API que manejará la carga de archivos / imágenes. Abra el uploadapp/views.pyarchivo y agregue el siguiente código:

from rest_framework.parsers import FileUploadParser
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status

from .serializers import FileSerializer


class FileUploadView(APIView):
    parser_class = (FileUploadParser,)

    def post(self, request, *args, **kwargs):

      file_serializer = FileSerializer(data=request.data)

      if file_serializer.is_valid():
          file_serializer.save()
          return Response(file_serializer.data, status=status.HTTP_201_CREATED)
      else:
          return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

FileUploadParser analiza el contenido de carga de archivos sin procesar. La request.datapropiedad será un diccionario con una sola clave que filecontiene el archivo cargado.

Thiw view procesará la solicitud http enviada a través HttpClientde la interfaz de Angular 10 para cargar la imagen.

Agregar la URL de carga

En uploadappcree un urls.pyarchivo y agregue el siguiente código, cree un extremo de carga de imágenes:

from django.urls import path
from .views import *

urlpatterns = [
    path('', FileUploadView.as_view())
]

A continuación, debe agregar la URL de medios y las uploadappURL en el urls.pyarchivo del proyecto:

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('upload/', include('uploadapp.urls')),
]


if settings.DEBUG:
  urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Después de eso, veremos cómo enviar solicitudes HTTP desde Angular 10 para subir archivos de imagen a nuestro servidor API REST Django 3.

Usando el static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)podemos servir archivos multimedia en modo de desarrollo.

A continuación, migre su base de datos y ejecute el servidor de desarrollo usando los siguientes comandos:

$ python manage.py migrate
$ python manage.py runserver

Su aplicación django 3 se ejecutará desde la http://127.0.0.1:8000/dirección. Si visita la dirección con su navegador web, debería ver la siguiente página:

Ejemplo de carga de archivo Django

Ahora puede probar su punto final de carga de archivos / imágenes utilizando un cliente de API REST como Postman:

Carga de archivos de la API REST de Django

Nota : asegúrese de nombrar el campo del archivo como file, que debe coincidir con el nombre del campo del modelo. En nuestro ejemplo es file.

Puede verificar si la mediacarpeta de su proyecto contiene el archivo cargado y puede acceder a su archivo cargado desde su navegador agregando la ruta recuperada en la respuesta a la URL de su servidor, es decir, http://127.0.0.1:8000/media/925364568cc67bfb7978b8cc65f40125_OEn02GOen nuestro ejemplo.

Habilitando CORS en Django 3

Dado que vamos a acceder a nuestro servidor de API REST de django 3 desde el frontend de Angular 10 a través de la HttpClientdirección, necesitamos habilitar CORS en nuestro backend de django 3. En su terminal, ejecute el siguiente comando para instalar django-cors-headers:

$ pip install django-cors-headers

A continuación, en su archivo de configuración, agregue corsheadersa la INSTALLED_APPSmatriz:

INSTALLED_APPS = [
    # [...]
    'corsheaders',
    'rest_framework',
    'uploadapp'
]

También necesita agregar corsheaders.middleware.CorsMiddlewareen la MIDDLEWAREmatriz:

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    # [...]
]

A continuación, agregue la siguiente configuración para habilitar CORS para todos los dominios:

CORS_ORIGIN_ALLOW_ALL =  True

Consulte más opciones en los documentos .

Creación de la aplicación de interfaz de usuario de Angular 10

Ahora, creemos la interfaz Angular 10 para cargar archivos de imagen en nuestro servidor de API REST de django 3. Abra una nueva terminal y ejecute el siguiente comando para instalar Angular CLI 10:

$ npm install -g @angular/cli

A continuación, usemos la interfaz de línea de comandos para generar un proyecto Angular 10:

$ cd django-file-upload
$ ng new frontend

Se le preguntará si desea agregar una ruta. Escriba y . Y también qué formato de hojas de estilo le gustaría usar, elija CSS . Luego presione Enter y espere a que la CLI genere los archivos de su proyecto e instale los paquetes desde npm.

A continuación, puede servir su aplicación usando el siguiente comando:

$ cd frontend
$ ng serve

Puede acceder a su aplicación desde la http://127.0.0.1:4200dirección.

Importando Angular HttpClientModuleyReactiveFormsModule

Trabajaremos con HttpClientformas angulares y reactivas en nuestro proyecto, por lo que necesitamos importar sus módulos en nuestra aplicación. Abra el src/app/app.module.tsarchivo y actualícelo en consecuencia:

// [...]
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    // [...]
    ReactiveFormsModule,
    HttpClientModule   
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Angular HttpClientse utilizará para enviar una solicitud POST que contiene datos de formulario creados mediante la FormDataadición del archivo de imagen con una fileclave. Esto nos permitirá subir la imagen a nuestro servidor API REST de django 3 que expone un /uploadpunto final para subir archivos de imagen.

Crear un servicio Angular 10

A continuación, creemos un servicio Angular 10 que encapsulará el código para cargar archivos de imagen en el servidor de la API REST de django 3. Abra una nueva terminal y ejecute el siguiente comando:

$ ng generate service upload

Abra el src/app/upload.service.tsarchivo y agregue el siguiente código:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})
export class UploadService {

  DJANGO_SERVER: string = "http://127.0.0.1:8000";
  constructor(private http: HttpClient) { }

  public upload(formData) {
    return this.http.post<any>(`${this.DJANGO_SERVER}/upload/`, formData);
  }
}

Primero importamos Angular HttpClienty lo inyectamos a través del constructor del servicio.

A continuación, definimos un upload()método que toma una instancia de FormDatay la envía al uploadpunto final de la API REST de Django con una solicitud POST.

Crear un componente y una forma de Angular 10

A continuación, creemos un componente Angular 10 que contenga el formulario que se utilizará para seleccionar el archivo o la imagen y carguemos el punto final de la API REST de django 3.

En su terminal, ejecute el siguiente comando:

$ ng generate component profile

A continuación, abra el src/app/app-routing.module.tsarchivo y agregue una ruta para el componente de perfil:

// [...]
import { ProfileComponent } from './profile/profile.component';

const routes: Routes = [
  {path: 'profile', component: ProfileComponent}
];

// [...]

A continuación, abra el src/app/profile/profile.component.tsarchivo y actualícelo en consecuencia:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { UploadService } from '../upload.service';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {

  DJANGO_SERVER = 'http://127.0.0.1:8000'
  form: FormGroup;
  response;
  imageURL;

  constructor(private formBuilder: FormBuilder, private uploadService: UploadService) { }

  ngOnInit() {
    this.form = this.formBuilder.group({
      profile: ['']
    });
  }

  onChange(event) {
    if (event.target.files.length > 0) {
      const file = event.target.files[0];
      this.form.get('profile').setValue(file);
    }
  }

  onSubmit() {
    const formData = new FormData();
    formData.append('file', this.form.get('profile').value);

    this.uploadService.upload(formData).subscribe(
      (res) => {
        this.response = res;
        this.imageURL = `${this.DJANGO_SERVER}${res.file}`;
        console.log(res);
        console.log(this.imageURL);
      },
      (err) => {  
        console.log(err);
      }
    );
  }
}

Primero creamos una forma reactiva de Angular 10 con un profilecampo en el ngOnInit()método del componente.

A continuación, definimos el onChange()método que se llama cuando el usuario elige una imagen en la fileinterfaz de entrada. W

Simplemente establecemos el archivo seleccionado como un valor del campo de perfil del formulario reactivo.

Finalmente, definimos el onSubmit()método al que se llama cuando hacemos clic en el botón enviar del formulario.

En este método, creamos un FormDataobjeto, agregamos el valor del profilecampo del formulario al filecampo (esto debe corresponder con el nombre del campo que espera el servidor django) y enviamos el FormDataobjeto al servidor de carga con una solicitud POST usando el UploadService.uploadmétodo.

A continuación, abra el src/app/profile.component.htmlarchivo y agregue el siguiente código:

<h1>Django REST API with Angular 10 Image Upload Example</h1>
<div>
  <div *ngIf="response && imageURL">
    <img [src]='imageURL' />
  </div>

  <form [formGroup]="form" (ngSubmit)="onSubmit()">

    <input type="file" name="profile" (change)="onChange($event)" />
    <button type="submit">Upload Image File</button>

  </form>
</div>

Creamos un formulario con un elemento de entrada para seleccionar el archivo de imagen que necesitas subir y un botón para subir la imagen al servidor API REST creado con django 3.

Esta es una captura de pantalla de la /profilepágina después de subir una imagen al servidor de django:

Carga de archivos de la API REST de Django con Angular 7

Conclusión

En este tutorial, hemos visto cómo crear un ejemplo de pila completa con Django 3 y Angular 10 para cargar archivos de imagen en un servidor API REST.

En el back-end, se utilizó Django marco RESTO, FileUploadParserFileFieldy que también permitió el uso de CORS django-cors-headers.

En la interfaz, solíamos FormDatacrear un objeto que corresponde a un formulario con multipart/form-datatipo y Angular 10 HttpClientpara enviar solicitudes POST al backend para cargar la imagen.


Publicar un comentario

0 Comentarios