J'ai le modèle suivant:
class Ticket(models.Model):
title = models.CharField()
merged_to = models.ForeignKey("self", related_name='merger_ticket', null=True, blank=True)
looser_ticket = models.BooleanField(default=False)
Il existe deux façons de manipuler le modèle:
Premier
ticket = Ticket.objects.get(pk=1)
ticket.title = "This is edit title"
ticket.merged_to_id = 2
ticket.looser_ticket = True
Deuxième
ticket = Ticket.objects.get(pk=1)
setattr(ticket, "title", "Edit Title")
setattr(ticket, "merged_to_id", 2)
setattr(ticket, "looser_ticket", True)
Lorsque je manipulais les choses, dans les vues de la mise à jour de la valeur booléenne, la première méthode ne fonctionnait pas, mais la deuxième méthode fonctionnait. Quelle est la différence entre utiliser le premier et le deuxième, et quand doit-on les utiliser?
Merci!
Il s'agit plus d'une question Python.
Python est un langage très dynamique. Vous pouvez coder des choses (classes) à l'avance, ou Python vous permet de créer des classes complètement dynamiquement au moment de l'exécution. Prenons l'exemple suivant d'une classe vectorielle simple. Vous pouvez créer/coder le classe à l'avance comme:
class MyVector(object):
x = 0
y = 0
ou vous pouvez créer la classe dynamiquement en faisant:
fields = {'x':0, 'y':0}
MyVector = type('MyVector', (object,), fields)
La principale différence entre les méthodes est que, pour celui que vous connaissez les attributs de classe à l'avance, tandis que pour la deuxième méthode, comme vous pouvez l'imaginer, vous pouvez créer par programme le dictionnaire fields
, donc vous pouvez créer une classe complètement dynamique ( es).
Ainsi, lorsque vous connaissez les attributs de la classe à l'avance, vous pouvez définir des attributs de classe à l'aide de la notation d'objet:
instance.attribute = value
Gardez à l'esprit que cela équivaut à:
instance.__setattr__(attribute, value)
Cependant, il existe des scénarios où vous ne connaissez pas les attributs de classe que vous devrez manipuler à l'avance. C'est ici que vous pouvez utiliser __setattr__
fonction. Cependant, ce n'est pas une pratique recommandée. Donc, à la place, la recommandation est d'utiliser la méthode intégrée de Python setattr
qui appelle en interne le __setattr__
méthode:
setattr(instance, attribute, value)
En utilisant cette approche, vous pouvez définir des attributs que vous ne connaissez pas à l'avance ou vous pouvez même boucler certains dict
et définir des valeurs à partir de dict:
values = {
'title': 'This is edit title',
...
}
for k, v in values.items():
setattr(ticket, k, v)
Je ne sais pas pourquoi la notation régulière n'a pas fonctionné. Cela n'a probablement rien à voir avec la méthode que vous avez utilisée pour définir les attributs.
Si vous connaissez les propriétés des objets à l'avance, vous devriez probablement utiliser la première méthode. Attribuez simplement des valeurs de propriété directement.
La seconde peut être utile lorsque vous devez affecter dynamiquement une valeur à une propriété. Peut-être qu'un utilisateur a la possibilité de modifier les valeurs d'un certain nombre d'attributs différents et que vous ne savez pas lequel aura une valeur à l'avance, vous pouvez ajouter dynamiquement des valeurs
possible_fields = ['title', 'looser_ticket']
ticket = Ticket.objects.get(pk=1)
for field in possible_fields:
if request.GET.get(field):
setattr(ticket, field, request.GET[field])
Le "ne fonctionne pas" ne dépend probablement pas de la façon dont vous définissez les valeurs, êtes-vous sûr d'avoir enregistré vos modifications par la suite ??