User Tag List

Resultados 1 al 7 de 7

Tema: Agregación Django

Vista híbrida

Mensaje anterior Mensaje anterior   Próximo mensaje Próximo mensaje
  1. #1
    Avatar de mbr386
    Fecha de ingreso
    Apr 2014
    Steam
    mbr386
    Origin
    mbr386
    Mensajes
    1,152

    Question Agregación Django

    Como va foro ?

    LLevo un par de días leyendo la documentación de Django y por stackoverflow, sinceramente debe ser mi nivel de inglés porque no puedo dar con la solución.

    Tengo una agregación y quiero representarla en el modelo, algo así:


    En la BD las agregaciones que tengo son como en el caso 1 (no se si afecta la cardinalidad de la relación dentro de la agregación para armarla), me falto agregar quizás un caso 3(1aN entre usuarios y la agregación) y 4(1a1 entre usuarios y la agregación).

    Ahora estoy tirando fruta para ver si llego a lo que debería ser... las clases me quedaron algo así:

    Spoiler: 

    class USUARIOS(AbstractUser):
    first_name = models.CharField(_("Nombre"), max_length=50, null=False)
    last_name = models.CharField(_("Apellido"), max_length=50, null=True, blank=True)
    email = models.EmailField(unique=True, max_length=100, null=False)
    Telefono = models.PositiveIntegerField(null=True, blank=True)
    Celular = models.PositiveIntegerField(null=True, blank=True)
    TipoUsuario = models.CharField(max_length=20, null=False)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username', 'first_name', 'TipoUsuario']


    Spoiler: 

    class MENSAJE(models.Model):
    Mensjae = models.TextField(max_length=500, null=False)


    Spoiler: 

    class NOTIFICACION(models.Model):
    FechaEnvio = models.TimeField(default=now, null=False)
    Mensaje = models.ForeignKey(MENSAJE, on_delete=models.CASCADE)


    Acá es donde quiero armar la agregación (pura fruta):

    Spoiler: 

    class USUARIO_NOTIFICACION_MENSAJE(models.Model):
    NotificacionMensaje = models.ManyToManyField(NOTIFICACION, through='USUARIO_NOTIFICACION_MENSAJE')
    Usuarios = models.ForeignKey(USUARIOS, on_delete=models.CASCADE, null=False)

    El resultado son 2 tablas
    1) USUARIO_NOTIFICACION_MENSAJE que tiene un ID y la clave foranea Usuarios
    2) USUARIO_NOTIFICACION_MENSAJE_NotificacionMensaje que tiene un ID, la clave foranea USUARIO_NOTIFICACION_MENSAJE y la clave foranea NOTIFICACION

    Acá si las cosas las hiciera bien debería tener: ID, clave foranea NOTIFICACION, clave foranea MENSAJE y clave foranea USUARIOS.


    Además de crear la agregación me gustaría que la clave de MENSAJE se propague a NOTIFICACION y no quede en otra tabla.

    La BD me debería quedar:

    TABLA 1: NOTIFICACION
    TABLA 2: MENSAJE
    TABLA 3: USUARIO
    TABLA 4: AGREGACIÓN (TABLAS 1,2 Y 3)

    Si soluciono me conformo con que quede así:

    TABLA 1: NOTIFICACION
    TABLA 2: MENSAJE
    TABLA 3: RELACIÓN (TABLAS 1 Y 2)
    TABLA 4: USUARIO
    TABLA 5: AGREGACIÓN (TABLAS 1,2 Y 3)

    Y ya que estoy, en que me cambia que yo arme la tabla a mano ?

    Desde ya les agradezco !!!

  2. #2
    El neandertal Avatar de Master of the Wind
    Fecha de ingreso
    Jul 2013
    Edad
    33
    Steam
    Master of the Wind
    Origin
    MasterOfTheWind1
    Xfire
    masterofthewind1
    Mensajes
    10,747
    Salgo del retiro, porque por lo que veo la Fundadora no participa fuera de su topic sagrado de feminismo, es un ejemplo de staff, le re importa su ideologia fascista, digo, el foro.



    Una agregacion que tiene una relacion N a 1 no tiene sentido, cuando se te da ese caso es mejor una relacion N a 1 con totalidad, y la relacion fuera de la relacion, la relacionas directamente con la entidad que tiene la N, en ese caso, yo haria

    [Usuario] -- N ---- <Generan> --- N -- [Notificacion] --N ----- o< Tienen > ---1- [Mensaje]

    Las relaciones N a 1 sin totalidad de por si no tienen mucho sentido, te generan una tabla mas que no aporta demasiado.

    Otra cosa, yo ahi tambien haria una relacion triple entre las 3, muy parecido al caso 1



    . [Notificacion] --N-----<Generan> ------1 [Mensaje]
    . ....................................|
    . ....................................|
    . ....................................|
    . ....................................N
    . ...............................[Usuario]


    Le pongo .... porque los espacios en blanco no andan

    La agregacion es solamente cuando las entidades de adentro se relacionan siempre, y ocacionalmente con la de afuera, si tenes 3 entidades relacionandose siempre, es mejor una relacion triple, da menos redundancia y mas consistencia.



    Django es un poco complejo con las tablas de relaciones porque le encanta hacer un id automaticamente como PK salvo que le digas lo contrario, y sobretodo, NO soporta claves primarias compuestas por mas de una columna.


    Fijate si te convence el modelo como te puse ahi y vemos como pilotearla en django.


    Que armes la tabla vos a mano en funcionamiento no te cambia nada, si usas migrations ganas consistencia, y como es codigo fuente, podes versionar la estructura de la db dentro del mismo codigo y no aparte, ademas que podes hacer rollback por ejemplo si una tabla queda mal definida, o si cambias un modelo, y generas y aplicas la migration le cambia la estructura a la tabla automaticamente.
    Última edición por Master of the Wind; 29-06-2020 a las 01:43 PM
    // Desktop: Core i5 13600KF - 32GB DDR4@3600 Mhz (16 GB DDR4 Thermaltake Thoughram + 16 GB DDR4 TForce VulcanZ) - Asus Prime Z690-P D4 - EVGA RTX 3090 FTW3 Ultra 24GB GDDR6X - SSD M.2 Kingston 2TB x2 - SSD M.2 Kingston 1TB - Thermaltake GF1 850W - Cooler Master Masterliquid 240 - Cooler Master H500 - Asus Strix Soar - Windows 11 x64
    // Gear:
    Razer Blackwidow V3 Mini 65% Hyperspeed - Razer Deathadder V2 Pro - Red Dragon Suzaku XL - Sony Dual Sense + Xbox Series Controller + 8BitDo USB Receiver 2 - Razer Kraken
    // Display: Gigabyte M32U 32" 4K@144hz
    // Retro: Core i3 6100 3.7Ghz - 8GB DDR4@2133 Mhz - 128 GB SSD - 1TB HDD - AMD Radeon R5 340X 2GB GDDR3 - 8 Bitdo SF30 Pro - Sony Wega Trinitron 36" CRT + VGA to Component transcoder - Batocera Linux
    // Work: Macbook Pro 15" 2019 - Core i9 2.3 Ghz - 16 GB DDR4 - 512 GB SSD - Intel UHD Graphcis 630/AMD Radeon Pro 560X 4GB GDDR5
    // Server ITX: Antec ISK 300 - Gigabyte GA AB350N Gaming WIFI - AMD Ryzen 3 3200g - 32GB RAM DDR4 - 1TB NVME SSD
    // Console peasant: New Nintendo 3DS XL 128GB MicroSD - Xbox 360 Slim 120GB - Nintendo Wii 512GB MicroSD - Nintendo Switch 256GB MicroSD + RCMLoader
    // Console no peasant: Steam Deck - 256GB SSD - 1TB MicroSD

  3. #3
    Avatar de mbr386
    Fecha de ingreso
    Apr 2014
    Steam
    mbr386
    Origin
    mbr386
    Mensajes
    1,152
    Cita Iniciado por Master of the Wind Ver mensaje
    Una agregacion que tiene una relacion N a 1 no tiene sentido, cuando se te da ese caso es mejor una relacion N a 1 con totalidad, y la relacion fuera de la relacion, la relacionas directamente con la entidad que tiene la N, en ese caso, yo haria

    [Usuario] -- N ---- <Generan> --- N -- [Notificacion] --N ----- o< Tienen > ---1- [Mensaje]

    Las relaciones N a 1 sin totalidad de por si no tienen mucho sentido, te generan una tabla mas que no aporta demasiado.

    Otra cosa, yo ahi tambien haria una relacion triple entre las 3, muy parecido al caso 1



    . [Notificacion] --N-----<Generan> ------1 [Mensaje]
    . ....................................|
    . ....................................|
    . ....................................|
    . ....................................N
    . ...............................[Usuario]


    Le pongo .... porque los espacios en blanco no andan

    La agregacion es solamente cuando las entidades de adentro se relacionan siempre, y ocacionalmente con la de afuera, si tenes 3 entidades relacionandose siempre, es mejor una relacion triple, da menos redundancia y mas consistencia.
    Lo veo bien en la noche y te digo.
    edit: ahora viendo el mer tiene mas sentido lo que decís, sale cambiazo.

    Cita Iniciado por Master of the Wind Ver mensaje
    Django es un poco complejo con las tablas de relaciones porque le encanta hacer un id automaticamente como PK salvo que le digas lo contrario, y sobretodo, NO soporta claves primarias compuestas por mas de una columna.
    Lo de generar ID lo había leído, creo que me puede servir la autogeneración de ID. Estoy haciendo un proyecto personal con la idea de aprender aun mas django y me encontré con esto que me superó. Seguro que a manopla anda pero quería hacerlo como django manda (por lo que leí podría ganar en armar las consultas mas fácil)

    Cita Iniciado por Master of the Wind Ver mensaje
    Fijate si te convence el modelo como te puse ahi y vemos como pilotearla en django.
    pss no va a servir, ya estoy viendo de cambiarlo.

    Cita Iniciado por Master of the Wind Ver mensaje
    Que armes la tabla vos a mano en funcionamiento no te cambia nada, si usas migrations ganas consistencia, y como es código fuente, podes versionar la estructura de la db dentro del mismo codigo y no aparte, ademas que podes hacer rollback por ejemplo si una tabla queda mal definida, o si cambias un modelo, y generas y aplicas la migration le cambia la estructura a la tabla automaticamente.
    en cada app se crea una carpeta migrations con los archivos de las migraciones. Siempre me dan problemas cuando modifico algo. Buscando encontré que la solución podía ser borrando esos archivos. Como vi que funciona ya lo hago por defecto


    El tema con django es que me gustaría hacerlo como django manda, me parece una chanchada hacerlo a mano. Se que se puede hacer porque ya lo hice, pero no quiero hacerlo siempre así.

  4. #4
    El neandertal Avatar de Master of the Wind
    Fecha de ingreso
    Jul 2013
    Edad
    33
    Steam
    Master of the Wind
    Origin
    MasterOfTheWind1
    Xfire
    masterofthewind1
    Mensajes
    10,747
    El tema con las migrations es que cuando haces un cambio en un model, tenes que ejecutar "python manage.py makemigrations [NOMBRE DE LA APP]", con eso no tenes margen de falla.


    El ID generado autonumerico esta bueno para algunas cosas, normalmente las tablas que representan entidades, para otras te rompe la integridad referencial a la mierda, a los campos que quieras que sean tu clave privada les podes poner UNIQUE, pero no se comporta como clave primaria, ya que son unicos los valores de cada columna y no la combinacion de ambas como si fuera una PK y termina rompiendo las pelotas, y terminas metiendo las FK de otras tablas como columnas normales y controlando por software el valor de ambas, y entras en lo que defino como la anomalía de la caja de zapatos: si vas a usar una base de datos que no controla nada, y tenes que hacer cosas por software, no estas usando una base de datos, es una caja de zapatos que le tiras cosas para adentro nomas.
    // Desktop: Core i5 13600KF - 32GB DDR4@3600 Mhz (16 GB DDR4 Thermaltake Thoughram + 16 GB DDR4 TForce VulcanZ) - Asus Prime Z690-P D4 - EVGA RTX 3090 FTW3 Ultra 24GB GDDR6X - SSD M.2 Kingston 2TB x2 - SSD M.2 Kingston 1TB - Thermaltake GF1 850W - Cooler Master Masterliquid 240 - Cooler Master H500 - Asus Strix Soar - Windows 11 x64
    // Gear:
    Razer Blackwidow V3 Mini 65% Hyperspeed - Razer Deathadder V2 Pro - Red Dragon Suzaku XL - Sony Dual Sense + Xbox Series Controller + 8BitDo USB Receiver 2 - Razer Kraken
    // Display: Gigabyte M32U 32" 4K@144hz
    // Retro: Core i3 6100 3.7Ghz - 8GB DDR4@2133 Mhz - 128 GB SSD - 1TB HDD - AMD Radeon R5 340X 2GB GDDR3 - 8 Bitdo SF30 Pro - Sony Wega Trinitron 36" CRT + VGA to Component transcoder - Batocera Linux
    // Work: Macbook Pro 15" 2019 - Core i9 2.3 Ghz - 16 GB DDR4 - 512 GB SSD - Intel UHD Graphcis 630/AMD Radeon Pro 560X 4GB GDDR5
    // Server ITX: Antec ISK 300 - Gigabyte GA AB350N Gaming WIFI - AMD Ryzen 3 3200g - 32GB RAM DDR4 - 1TB NVME SSD
    // Console peasant: New Nintendo 3DS XL 128GB MicroSD - Xbox 360 Slim 120GB - Nintendo Wii 512GB MicroSD - Nintendo Switch 256GB MicroSD + RCMLoader
    // Console no peasant: Steam Deck - 256GB SSD - 1TB MicroSD

  5. #5
    El neandertal Avatar de Master of the Wind
    Fecha de ingreso
    Jul 2013
    Edad
    33
    Steam
    Master of the Wind
    Origin
    MasterOfTheWind1
    Xfire
    masterofthewind1
    Mensajes
    10,747
    Los modelos estan bien definidos, segui en esa linea nomas y vas a andar bien.

    Un par de detalles de convenciones de codigo, no le pongas nombres a las clases en mayuscula, solo pone en mayuscula la primer letra de cada palabra (por ejemplo, si tuvieras una clase Usuario Especial, tendria que llamarse UsuarioEspecial).

    Lo mismo podes hacer con las variables Fields para los selectors, en vez de separar con _ podes poner "UsernameFields", eso es una convencion de casing que lo podes aplicar todo: clases, funciones, variables, instancias, etc, normalmente lo que se hace es cuando un elemento es publico la primer letra de la primer palabra empieza en mayuscula, y cuando es privado o local es en minuscula, pero seguis saltando de palabra con mayuscula (se llaman Camel Casing para los elementos privados o locales y Pascal Casing para los elementos publicos, por si queres seguir viendo mas)

    Por ejemplo

    clasePrivada
    ClasePublica

    FuncionPublica
    funcionLocal

    Te queda mucho mas natural, usable y entendible en el codigo.



    Vuelvo a mi retiro pro facismo, no sea cosa que la fundadora se entere que volvi y pida mi nai cabeza para tirarle el ban-hammer por hate-speech, aunque lo dudo ya que no entra al 90% del foro.
    Última edición por Master of the Wind; 29-06-2020 a las 07:30 PM
    // Desktop: Core i5 13600KF - 32GB DDR4@3600 Mhz (16 GB DDR4 Thermaltake Thoughram + 16 GB DDR4 TForce VulcanZ) - Asus Prime Z690-P D4 - EVGA RTX 3090 FTW3 Ultra 24GB GDDR6X - SSD M.2 Kingston 2TB x2 - SSD M.2 Kingston 1TB - Thermaltake GF1 850W - Cooler Master Masterliquid 240 - Cooler Master H500 - Asus Strix Soar - Windows 11 x64
    // Gear:
    Razer Blackwidow V3 Mini 65% Hyperspeed - Razer Deathadder V2 Pro - Red Dragon Suzaku XL - Sony Dual Sense + Xbox Series Controller + 8BitDo USB Receiver 2 - Razer Kraken
    // Display: Gigabyte M32U 32" 4K@144hz
    // Retro: Core i3 6100 3.7Ghz - 8GB DDR4@2133 Mhz - 128 GB SSD - 1TB HDD - AMD Radeon R5 340X 2GB GDDR3 - 8 Bitdo SF30 Pro - Sony Wega Trinitron 36" CRT + VGA to Component transcoder - Batocera Linux
    // Work: Macbook Pro 15" 2019 - Core i9 2.3 Ghz - 16 GB DDR4 - 512 GB SSD - Intel UHD Graphcis 630/AMD Radeon Pro 560X 4GB GDDR5
    // Server ITX: Antec ISK 300 - Gigabyte GA AB350N Gaming WIFI - AMD Ryzen 3 3200g - 32GB RAM DDR4 - 1TB NVME SSD
    // Console peasant: New Nintendo 3DS XL 128GB MicroSD - Xbox 360 Slim 120GB - Nintendo Wii 512GB MicroSD - Nintendo Switch 256GB MicroSD + RCMLoader
    // Console no peasant: Steam Deck - 256GB SSD - 1TB MicroSD

  6. #6
    Avatar de mbr386
    Fecha de ingreso
    Apr 2014
    Steam
    mbr386
    Origin
    mbr386
    Mensajes
    1,152
    Cita Iniciado por Master of the Wind Ver mensaje
    Los modelos estan bien definidos, segui en esa linea nomas y vas a andar bien.

    Un par de detalles de convenciones de codigo, no le pongas nombres a las clases en mayuscula, solo pone en mayuscula la primer letra de cada palabra (por ejemplo, si tuvieras una clase Usuario Especial, tendria que llamarse UsuarioEspecial).

    Lo mismo podes hacer con las variables Fields para los selectors, en vez de separar con _ podes poner "UsernameFields", eso es una convencion de casing que lo podes aplicar todo: clases, funciones, variables, instancias, etc, normalmente lo que se hace es cuando un elemento es publico la primer letra de la primer palabra empieza en mayuscula, y cuando es privado o local es en minuscula, pero seguis saltando de palabra con mayuscula (se llaman Camel Casing para los elementos privados o locales y Pascal Casing para los elementos publicos, por si queres seguir viendo mas)

    Por ejemplo

    clasePrivada
    ClasePublica

    FuncionPublica
    funcionLocal

    Te queda mucho mas natural, usable y entendible en el codigo.



    Vuelvo a mi retiro pro facismo, no sea cosa que la fundadora se entere que volvi y pida mi nai cabeza para tirarle el ban-hammer por hate-speech, aunque lo dudo ya que no entra al 90% del foro.
    Ahí tenes razón, las convenciones para que ja.
    Las puse en mayúscula porque así entendía rápido que era el nombre de la clase, no recuerdo por qué cuando estaba haciendo el otro proyecto (también para aprender) me confundía con algo, no recuerdo. se que lo había nombrado muy parecido (cambiaba alguna letra en mayúscula, igual se me complicaba) y me armaba tremendo pedo.

    Y respecto a las migraciones, yo uso a secas "py manage.py makemigrations". Claro, por eso me debe dar pila de problemas. voy a empezar a usar la migración solo de la app que modifico

  7. #7
    Avatar de mbr386
    Fecha de ingreso
    Apr 2014
    Steam
    mbr386
    Origin
    mbr386
    Mensajes
    1,152
    Leyendo un poco mas en la web de django dicen que usar ManyToManyField es lo mismo que ForeignKey, así que bueno. Sale con ForeignKey y la tabla a manopla (igual voy a seguir leyendo porque como dije antes me gustaría seguir aplicar ManyToManyField).
    Lo otro es que justo esas relaciones las podía simplificar un poco más, 2 tablas para guardar 1 atributo. Creo que lo voy a dejar así:



    De todos modos me sirve lo que comentaste master porque tengo 3 agregaciones más que podría revisar, son candidatas a cambiarse.

    Gracias cHe!

Información de tema

Usuarios viendo este tema

Actualmente hay 1 usuarios viendo este tema. (0 miembros y 1 visitantes)

Permisos de publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •