Actualmente tengo muchos objetos de python en mi código similares a los siguientes:
class MyClass():
def __init__(self, name, friends):
self.myName = name
self.myFriends = [str(x) for x in friends]
Ahora quiero convertir esto en un modelo de Django, donde self.myName es un campo de cadena y self.myFriends es una lista de cadenas.
from django.db import models
class myDjangoModelClass():
myName = models.CharField(max_length=64)
myFriends = ??? # what goes here?
Dado que la lista es una estructura de datos tan común en python, esperaba que hubiera un campo modelo de Django para ella. Sé que puedo usar una relación ManyToMany o OneToMany, pero esperaba evitar esa indirección adicional en el código.
Editar:
Agregué esta pregunta relacionada , que la gente puede encontrar útil.
python
django
django-models
afligirse
fuente
fuente
Respuestas:
¿Esta relación no se expresaría mejor como una relación de clave externa de uno a muchos con una
Friends
tabla? Entiendo quemyFriends
son solo cadenas, pero creo que un mejor diseño sería crear unFriend
modelo yMyClass
contener una relación de clave externa para la tabla resultante.fuente
"La optimización temprana es la raíz de todo mal."
Con eso en mente, ¡hagamos esto! Una vez que sus aplicaciones llegan a cierto punto, la desnormalización de datos es muy común. Hecho correctamente, puede ahorrar numerosas búsquedas costosas de bases de datos a costa de un poco más de limpieza.
Para devolver un nombre
list
de amigo, necesitaremos crear una clase de campo Django personalizada que devolverá una lista cuando se acceda.David Cramer publicó una guía para crear un SeperatedValueField en su blog. Aquí está el código:
La lógica de este código trata de serializar y deserializar valores de la base de datos a Python y viceversa. Ahora puede importar y usar fácilmente nuestro campo personalizado en la clase de modelo:
fuente
my_vals = SeparatedValuesField(blank=True, default="")
pero obteniendo IntegrityError debido a NULLs. ¿El argumento predeterminado no se pasa correctamente?to_python
ya no se requiere lectura. Por lo tanto, para que esto funcione, debe agregar:def from_db_value(self, value, expression, connection, context): return self.to_python(value)
Una forma sencilla de almacenar una lista en Django es simplemente convertirla en una cadena JSON y luego guardarla como Texto en el modelo. Luego puede recuperar la lista convirtiendo la cadena (JSON) nuevamente en una lista de Python. Así es cómo:
La "lista" se almacenaría en su modelo de Django así:
En su código de vista / controlador:
Almacenar la lista en la base de datos:
Recuperando la lista de la base de datos:
Conceptualmente, esto es lo que está sucediendo:
fuente
Si está utilizando Django> = 1.9 con Postgres, puede aprovechar las ventajas de ArrayField
También es posible anidar campos de matriz:
Como @ thane-brimhall mencionó, también es posible consultar elementos directamente. Referencia de la documentación
fuente
Como esta es una pregunta antigua, y las técnicas de Django deben haber cambiado significativamente desde entonces, esta respuesta refleja la versión 1.4 de Django, y probablemente sea aplicable para la versión 1.5.
Django por defecto usa bases de datos relacionales; deberías usarlos. Asigne amistades a relaciones de bases de datos (restricciones de clave externa) con el uso de ManyToManyField. Hacerlo le permite usar RelatedManagers para listas de amigos, que usan conjuntos de consultas inteligentes. Puede usar todos los métodos disponibles como
filter
ovalues_list
.Usando
ManyToManyField
relaciones y propiedades:Puede acceder a la lista de amigos de un usuario de esta manera:
Sin embargo, tenga en cuenta que estas relaciones son simétricas: si Joseph es amigo de Bob, entonces Bob es amigo de Joseph.
fuente
fuente
Recuerde que esto finalmente tiene que terminar en una base de datos relacional. Entonces, usar las relaciones es realmente la forma común de resolver este problema. Si insiste absolutamente en almacenar una lista en el propio objeto, podría hacerlo, por ejemplo, separado por comas, y almacenarlo en una cadena, y luego proporcionar funciones de acceso que dividen la cadena en una lista. Con eso, estará limitado a un número máximo de cadenas y perderá consultas eficientes.
fuente
En caso de que estés usando postgres, puedes usar algo como esto:
Si necesita más detalles, puede leer en el siguiente enlace: https://docs.djangoproject.com/pt-br/1.9/ref/contrib/postgres/fields/
fuente
Puede almacenar prácticamente cualquier objeto usando un campo Django Pickle Field, como este fragmento:
http://www.djangosnippets.org/snippets/513/
fuente
Almacenar una lista de cadenas en el modelo Django:
y puedes llamarlo así:
fuente
Mi solución, puede ser que ayude a alguien:
fuente
El uso de la relación uno a muchos (FK de amigo a clase principal) hará que su aplicación sea más escalable (ya que puede extender trivialmente el objeto amigo con atributos adicionales más allá del nombre simple). Y esta es la mejor manera.
fuente