2016-01-20 8 views
6

Ich habe viele Hardware Modelle, die eine HardwareType mit verschiedenen Eigenschaften haben. Wie so:Wie überschreibt man die model.Manager.create() Methode in Django?

# models.py 
from django.db import models 

class HardwareType(model.Models): 
    name = models.CharField(max_length=32, unique=True) 

    # some characteristics of this particular piece of hardware 
    weight = models.DecimalField(max_digits=12, decimal_places=3) 
    # and more [...]   

class Hardware(models.Model): 

    type = models.ForeignKey(HardwareType) 

    # some attributes 
    is_installed = models.BooleanField() 
    location_installed = models.TextField() 
    # and more [...] 

Wenn ich ein neues Hardware Objekt hinzufügen wollen, ich muss zuerst die HardwareType jedes Mal abrufen, die nicht sehr trocken ist:

tmp_hd_type = HardwareType.objects.get(name='NG35001') 
new_hd = Hardware.objects.create(type=tmp_hd_type, is_installed=True, ...) 

Deshalb habe ich versucht, außer Kraft zu setzen die HardwareManager.create() Methode, um automatisch die Art zu importieren, wenn neue Hardware wie das Erstellen so:

# models.py 
from django.db import models 

class HardwareType(model.Models): 
    name = models.CharField(max_length=32, unique=True) 

    # some characteristics of this particular piece of hardware 
    weight = models.DecimalField(max_digits=12, decimal_places=3) 
    # and more [...] 

class HardwareManager(models.Manager): 
    def create(self, *args, **kwargs): 
     if 'type' in kwargs and kwargs['type'] is str: 
      kwargs['type'] = HardwareType.objects.get(name=kwargs['type']) 
     super(HardwareManager, self).create(*args, **kwargs)  

class Hardware(models.Model): 
    objects = HardwareManager() 

    type = models.ForeignKey(HardwareType) 

    # some attributes 
    is_installed = models.BooleanField() 
    location_installed = models.TextField() 
    # and more [...] 

# so then I should be able to do: 
new_hd = Hardware.objects.create(type='ND35001', is_installed=True, ...) 

Aber ich erhalte immer Fehler und wirklich s Verhalten aus dem ORM (Ich habe sie nicht hier, aber ich kann sie bei Bedarf veröffentlichen). Ich habe in der Django-Dokumentation und die SO Themen gesucht, aber meistens ich auf Lösungen landen, wo: (soll ich die HardwareType dort)

  • die Hardware.save() Methode überschrieben wird, oder
  • die Manager definiert eine neue create_something Methode, die self.create() aufruft.

Ich begann auch in den Code zu graben und sah, dass die Manager einig besondere Art von QuerySet ist, aber ich weiß nicht, wie von dort fortzusetzen. Ich möchte wirklich die create Methode an Ort und Stelle ersetzen und ich kann nicht scheinen, das zu verwalten. Was hindert mich daran, das zu tun, was ich tun möchte?

Antwort

1

Die Einsicht von Alasdair ‚s Antwort hat mir sehr geholfen, um beide Strings und Unicode-Strings zu fangen, aber was eigentlich fehlte, war eine return Anweisung vor dem Aufruf von super(HardwareManager, self).create(*args, **kwargs) im HardwareManager.create() Verfahren.

Die Fehler, die ich in meinen Tests gestern Abend bekommen (müde bei der Codierung ist keine gute Idee: P) waren ValueError: Cannot assign None: [...] does not allow null values. weil die anschließende Verwendung von new_hd, die ich create() d hatte wurde None weil mein create() Methode nicht haben a return. Was für ein dummer Fehler!

Schluss korrigierte Code:

class HardwareManager(models.Manager): 
    def create(self, *args, **kwargs): 
     if 'type' in kwargs and isinstance(kwargs['type'], basestring): 
      kwargs['type'] = HardwareType.objects.get(name=kwargs['type']) 
     return super(HardwareManager, self).create(*args, **kwargs) 
2

Ohne die Traceback zu sehen, denke ich, das Problem ist in dieser Zeile.

if 'type' in kwargs and kwargs['type'] is str: 

Dies ist zu prüfen, ob kwargs['type'] ist das gleiche Objekt wie str, die immer falsch sein wird.

In Python 3, zu prüfen, ob `kwargs [ 'type'] ist ein String, sollten Sie tun:

if 'type' in kwargs and isinstance(kwargs['type'], str): 

Wenn Sie Python 2 verwenden, sollten Sie basestring verwenden, Byte-Strings zu fangen und Unicode-Zeichenfolgen.

if 'type' in kwargs and isinstance(kwargs['type'], basestring): 
+0

Ich werde versuchen, dies in ein paar Stunden und zurück zu Ihnen mit den Fehlern (falls vorhanden) bekommen. Vielen Dank ! – achedeuzot

+3

In 2.x Sie können 'isinstance (foo, basestring)' verwenden, um sowohl Unicode als auch str zu erfassen. –

+0

@DanielRoseman verwendet 'Manager.create' die' model.save' Methode, die im Modell definiert ist oder nicht? – DhiaTN

Verwandte Themen