Django REST Framework - ListSerializer - Actualizaciones Múltiples

Imagen
 Se muestra un ejemplo, de como realizar la implementación de Múltiples actualizaciones en una sola petición , es decir enviando una lista de objetos, y usando la clase ListSerializer  realizamos las actualizaciones (inserciones u eliminaciones). El modelo para el ejemplo La Vista      def   post ( self ,  request ):          """ Ejemplo de manejo de listas en Serializer                     Para este ejemplo asumimos lo siguiente:           Se tienen que enviar todos los datos existentes de los empleados en el JSON ya que           se comparara con la base de datos y :            1.- Si se encuentran se actualizan los datos,            2.- Si no existen en la base de datos  se crean,            3.- Si se encuentran en la base de datos, pero no fueron pasados en el JSON se elimnan.          """          # Obtener el  JSON.          data  =  request .data          # Obtener los datos de la base de datos                  emp  =  Employes . objects . all ()   

Personalizando la comparación del comando Union de Linq

Union de Linq, nos permite unir el contenido de diferentes arreglos en uno solo, comparando el objeto completo,veamos un ejemplo:


Creamos una clase con dos campos.
public class Foo
{
        public string Campo1;
        public string Campo2;

        public Foo(string pCampo1, string pCampo2)
        {
            this.Campo1 = pCampo1;
            this.Campo2 = pCampo2;
        }
}





public class TestFoo
{ 
        public TestFoo()
        {
            //Creamos dos Arreglos, para Testear.
            List<Foo> foo = new List<Foo>()
                            { new Foo("campo1", "campo22"), 
                              new Foo("campo3", "campo3"), 
                              new Foo("campox", "campoy") };
            List<Foo> foo2 = new List<Foo>() 
                              { new Foo("campo11", "campo22"), 
                                new Foo("campo3", "campo3"), 
                                new Foo("campoxx", "campoy") };

            //Unimos los dos arreglos.
            List foo3 = foo.Union(foo2);

            foreach (Foo item in foo3)
            {
                System.Diagnostics.Debug.WriteLine(
                                  item.Campo1 +"," + item.Campo2);
            } 
        }
    }
Devolvera:
      "campo1","campo22"
      "campo3","campo3"
      "campox","campoy"
      "campo11","campo22"
      "campoxx","campoyy"




Si nos damos cuenta Union, compara el contenido de todo el objeto y devuelve un arreglo con los objetos diferentes.


Si desearamos comparar únicamente ciertos campos, por ejemplo en nuestra clase queremos devolver los objetos que tengan relación únicamente con el campo2:
Debemos tener algo como: (comparación   foo.Campo2=foo2.Campo2).
campo1, campo22
campo3,campo3





campox,campoy

 Al intentar realizar esto, intente usar algún tipo de lambda expression, pero sorpresa el parámetro Union solo acepta dos sobrecargas de objetos :

public static IEnumerable Union(
 this IEnumerable first,
 IEnumerable second,
 IEqualityComparer comparer
)
Si nos fijamos en la segunda sobrecarga, nos pide un objeto de tipo IEqualityComparer, leyendo la documentación de Microsoft, esta interfaz nos permite declarar una clase para personalizar la comparación del comando Union.
Creamos la clase FooComparer para personalizar la comparación, de nuestros arreglos unicamente con el campo2.





class FooComparer : IEqualityComparer<Foo>
    {
        public bool Equals(Foo x, Foo y)
        {
            if (!Object.ReferenceEquals(x, null) && 
                 !object.ReferenceEquals(y, null)) //&& !Object.ReferenceEquals(x,y)
            {
                return x.Campo2.ToUpper() == y.Campo2.ToUpper();
            }
            return false;
        }
        public int GetHashCode(Foo obj)
        {
            if (ReferenceEquals(obj, null)) return 0;
            int hashCampo2 = objCampo2.GetHashCode();
          //int hashCampo1 = objCampo1.GetHashCode();
            return hashCampo2; //^ hashCampo1 ;
        }
    }
Lo importante esta en el codigo Hash calculado, si quisieramos comparar otros campos del objeto, habrá que calcular el hash para estos campos y devolver algo como campo a codeHash1 codeHash2, etc. 

Para probar nuestra clase: 
List foo3 = foo.Union(foo2, new FooComparer());

Devolverá:
campo1, campo22
campo3,campo3
campox,campoy





Comentarios

Entradas populares de este blog

Django. [Errno 10013] Intento de Acceso a un Socket no Permitido por sus permisos de acceso.

Crystal Reports para VS2010. El Texto Restante no parece se parte de la Formula.

ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)