J'écris et j'utilise une application pour gérer mes équipements réseau. J'ai créé un modèle, RJ45port, que je peux ajouter à mon équipement au besoin. Un port RJ45 peut être branché sur un autre port RJ45 et un seul.
Voici le modèle que j'ai créé:
def save(self, *args, **kwargs): super(RJ45port, self).save() self.plugged_into.plugged_into = self
Quand je "branche" un port RJ45 dans un autre, je veux que le second ait "plugged_into" réglé sur le premier . Je veux que la relation soit symétrique. Si je "débranche", je veux que les deux ports RJ45 aient "plugged_into" mis à null ou vide.
J'ai trouvé un peu de code, ça pourrait être un indice:
class RJ45port(models.Model): plugged_into = models.OneToOneField('self', on_delete=models.SET_NULL, blank=True, null=True)
Pour être honnête je suis un peu perdu ici et c'est la dernière étape J'ai besoin de rendre cette application fonctionnelle ...
3 Réponses :
Vous êtes mieux adapté en créant simplement une méthode modèle plug_into ()
, puis en l'utilisant pour "brancher" une instance dans une autre, ainsi qu'un unplug ()
Exemple:
port_1 = Port.objects.all()[0] # First port port_2 = Port.objects.all()[1] # Second port port_1.plug_into(port_2) # Should return [instance, instance] port_1.unplug() # Should return [None, None]
Et puis vous pouvez l'appeler comme ceci:
class RJ45port(models.Model): plugged_into = models.OneToOneField('self', on_delete=models.SET_NULL, blank=True, null=True) def plug_into(self, instance): self.plugged_into = instance instance.plugged_into = self self.save(update_fields=['plugged_into']) instance.save(update_fields=['plugged_into']) return [self.plugged_into, instance.plugged_into] def unplug(self): self.plugged_into.plugged_into = None self.plugged_into = None self.plugged_into.save(update_fields=['plugged_into']) self.save(update_fields=['plugged_into']) return [self.plugged_into, instance.plugged_into]
Cela semble intéressant, mais comment appeler plug_into et le débrancher dans ma page d'administration?
@vjuluss Je remplacerais la méthode admin save_model ()
pour appeler les méthodes plug_int ()
et unplug ()
. Un exemple peut être montré ici: stackoverflow.com/a/21852651/3345051
si self.plugged_into, appelez plug_into, sinon appelez unplug?
@vjuluss Je vérifierais si l'instance a changé, et si c'est le cas, j'appelle obj.plug_into ()
ou obj.unplug ()
selon s'il y a une nouvelle valeur pour obj.plugged_into
. Vous pouvez voir comment procéder ici stackoverflow.com/questions/8056179/...
Eh bien, je ne peux pas le faire fonctionner ... ça ne devrait pas fonctionner sur un problème comme celui-ci à la fin de la journée ...
@vjuluss Pas de problème! Parfois, vous devez faire une pause pour avoir l'esprit clair. Je voudrais vous aider davantage, mais cela devient très difficile car je n'ai pas un bon environnement de test. Vous devriez réessayer bientôt, et vous pourrez toujours poser une autre question concernant le remplacement de save_model ()
dans django admin (dont je connais très peu). J'espère que quelqu'un pourra vous aider à résoudre cette deuxième partie du problème.
Vous avez raison. Remplacez simplement la méthode de sauvegarde. Mais appelez super (). Save ()
à la fin:
class RJ45port(models.Model): plugged_into = models.OneToOneField('self', on_delete=models.SET_NULL, blank=True, null=True) def save(self, *args, **kwargs): self.plugged_into.plugged_into = self super(RJ45port, self).save()
Il y a trois problèmes avec cela. 1) self.plugged_into.plugged_into
n'est jamais enregistré, 2) Il y a une condition de concurrence si vous utilisez self.plugged_into.plugged_into.save () code> - qui se produira en premier, le
.save ()
de l'instance secondaire ou l'instance initiale? 3) Il y aura une boucle infinie de méthodes save ()
qui s’appelleront
Le problème avec ceci est que lorsque je veux "débrancher", Django renvoie une erreur disant que None n'a pas d'objet "plugged_into"
Une autre option consiste à utiliser un related_name
afin de pouvoir effectuer un accès inverse à partir de l'instance référencée, de sorte que vous puissiez dire que la relation devient "symétrique". Le seul inconvénient est que vous ne pouvez pas utiliser le même nom pour référencer les deux connexions:
class RJ45port(models.Model): plugged_into = models.OneToOneField('self', on_delete=models.SET_NULL, blank=True, null=True, related_name='plugged_from')
Dans cet exemple, plugged_from
peut être interrogé comme n'importe quel autre champ du instance référencée.
Je pense comprendre votre suggestion. Je pourrais essayer plus tard quand je pourrai coder. Mais je ne pense pas que cela montrera la connexion inverse dans l'interface d'administration ...?