Actuellement, j'ai beaucoup d'objets python dans mon code similaires à ce qui suit:
class MyClass():
def __init__(self, name, friends):
self.myName = name
self.myFriends = [str(x) for x in friends]
Maintenant, je veux transformer cela en un modèle Django, où self.myName est un champ de chaîne et self.myFriends est une liste de chaînes.
from django.db import models
class myDjangoModelClass():
myName = models.CharField(max_length=64)
myFriends = ??? # what goes here?
Étant donné que la liste est une structure de données si commune en python, je m'attendais à ce qu'il y ait un champ de modèle Django pour cela. Je sais que je peux utiliser une relation ManyToMany ou OneToMany, mais j'espérais éviter cette indirection supplémentaire dans le code.
Éditer:
J'ai ajouté cette question connexe , que les gens peuvent trouver utile.
python
django
django-models
pleurer
la source
la source
Réponses:
Cette relation ne serait-elle pas mieux exprimée comme une relation de clé étrangère un-à-plusieurs à une
Friends
table? Je comprends que ce nemyFriends
sont que des chaînes, mais je pense qu'une meilleure conception serait de créer unFriend
modèle et deMyClass
contenir une relation de clé étrangère vers la table résultante.la source
"L'optimisation prématurée est la racine de tout Mal."
Avec cela fermement à l'esprit, faisons ceci! Une fois que vos applications ont atteint un certain point, la dénormalisation des données est très courante. Fait correctement, il peut économiser de nombreuses recherches coûteuses dans la base de données au prix d'un peu plus d'entretien.
Pour renvoyer un
list
des noms d'amis, nous devrons créer une classe Django Field personnalisée qui renverra une liste lors de l'accès.David Cramer a publié un guide pour créer un SeperatedValueField sur son blog. Voici le code:
La logique de ce code traite de la sérialisation et de la désérialisation des valeurs de la base de données vers Python et vice versa. Maintenant, vous pouvez facilement importer et utiliser notre champ personnalisé dans la classe de modèle:
la source
my_vals = SeparatedValuesField(blank=True, default="")
mais obtenant IntegrityError en raison de NULL. L'argument par défaut n'est-il pas transmis correctement?to_python
n'est plus appelé en lecture. Ainsi, pour faire ce travail, vous devez ajouter:def from_db_value(self, value, expression, connection, context): return self.to_python(value)
Un moyen simple de stocker une liste dans Django consiste simplement à la convertir en chaîne JSON, puis à l'enregistrer en tant que texte dans le modèle. Vous pouvez ensuite récupérer la liste en reconvertissant la chaîne (JSON) en une liste python. Voici comment:
La "liste" serait stockée dans votre modèle Django comme ceci:
Dans votre vue / code contrôleur:
Stockage de la liste dans la base de données:
Récupération de la liste de la base de données:
Conceptuellement, voici ce qui se passe:
la source
Si vous utilisez Django> = 1.9 avec Postgres, vous pouvez profiter des avantages d' ArrayField
Il est également possible d'imbriquer des champs de tableau:
Comme @ thane-brimhall l'a mentionné, il est également possible d'interroger des éléments directement. Référence de la documentation
la source
Comme il s'agit d'une vieille question et que les techniques de Django ont dû changer considérablement depuis, cette réponse reflète Django version 1.4, et est probablement applicable pour la v 1.5.
Django utilise par défaut des bases de données relationnelles; vous devriez les utiliser. Mappez les amitiés aux relations de base de données (contraintes de clé étrangère) avec l'utilisation de ManyToManyField. Cela vous permet d'utiliser RelatedManagers pour les listes d'amis, qui utilisent des ensembles de requêtes intelligents. Vous pouvez utiliser toutes les méthodes disponibles telles que
filter
ouvalues_list
.En utilisant
ManyToManyField
relations et des propriétés:Vous pouvez accéder à la liste d'amis d'un utilisateur de cette façon:
Notez cependant que ces relations sont symétriques: si Joseph est un ami de Bob, alors Bob est un ami de Joseph.
la source
la source
N'oubliez pas que cela doit finir par aboutir dans une base de données relationnelle. Donc, utiliser les relations est vraiment le moyen le plus courant de résoudre ce problème. Si vous insistez absolument pour stocker une liste dans l'objet lui-même, vous pouvez la créer, par exemple, séparée par des virgules, et la stocker dans une chaîne, puis fournir des fonctions d'accesseur qui divisent la chaîne en une liste. Avec cela, vous serez limité à un nombre maximum de chaînes et vous perdrez des requêtes efficaces.
la source
Si vous utilisez postgres, vous pouvez utiliser quelque chose comme ceci:
si vous avez besoin de plus de détails, vous pouvez lire le lien ci-dessous: https://docs.djangoproject.com/pt-br/1.9/ref/contrib/postgres/fields/
la source
Vous pouvez stocker pratiquement n'importe quel objet en utilisant un Django Pickle Field, ala cet extrait:
http://www.djangosnippets.org/snippets/513/
la source
Stockage d'une liste de chaînes dans le modèle Django:
et vous pouvez l'appeler comme ceci:
la source
L'utilisation de la relation un-à-plusieurs (FK de la classe Friend vers la classe parente) rendra votre application plus évolutive (car vous pouvez étendre trivialement l'objet Friend avec des attributs supplémentaires au-delà du simple nom). Et c'est donc la meilleure façon
la source
Ma solution, peut-être qu'elle aide quelqu'un:
la source