2017-12-28 7 views
1

Ich habe eine Klasse in meinem models.pyPython - Wie zwei Modellfelder in models.py in Django hinzufügen

class Inventory(models.Model): 
    date = models.DateField(("Date"), default=datetime.now) 
    product = models.ForeignKey(Product) 
    stock_in = models.IntegerField() 
    stock_out = models.IntegerField() 
    balance = models.IntegerField() 
    particulars = models.CharField(max_length=250) 

Jetzt habe ich einige Aktien in der Bilanz hinzufügen möchten. Verwenden Sie die Werte stock_in, um dem Bestand eines bestimmten Produkts in der Inventory-Klasse bestimmte Zahlen hinzuzufügen. Verwenden Sie eine UpdateView, damit ich nur das stock_in Feld aktualisieren kann, dann diesen Wert zum Kontostand hinzufügen.

Ich benutze derzeit dies, ich habe versucht paar Lösung im Internet, aber ohne Erfolg.

@property 
    def total(self): 
     return self.stock_in + self.balance 
+0

Sollen 'balance' den aktuellen Bestand und' stock_ [in | out] 'die laufenden Summen von ein- und ausgehenden Posten bezeichnen? So dass: balance == initial_balance + stock_in - stock_out? – schwobaseggl

Antwort

0

Es gibt keinen offiziellen Mechanismus in Django, um dies zu tun. Vor kurzem wurden einige Ideen zur Einführung einer offiziellen Lösung für das Django-Framework in der Mailingliste django-developers unter this thread diskutiert. Es könnte als Inspiration für die aktuell beste Lösung für Ihren Fall dienen.

Ihre Methode funktioniert gut für einfache Berechnungen. Wenn die Berechnung der Eigenschaft teurer wird, kann die Verwendung von @cached_property ein wenig helfen, wenn der Wert mehrmals verwendet wird.

Sie können sich auch darauf verlassen, dass die Datenbank diese Werte berechnet, indem Sie dem Queryset eine Anmerkung hinzufügen. Dies erfordert die Definition eines benutzerdefinierten Manager:

class InventoryManager(models.Manager): 
    def get_queryset(self): 
     super().get_queryset().annotate(total=F('stock_in') + F('balance')) 

class Inventory(models.Model): 
    date = models.DateField(("Date"), default=datetime.now) 
    product = models.ForeignKey(Product) 
    stock_in = models.IntegerField() 
    stock_out = models.IntegerField() 
    balance = models.IntegerField() 
    particulars = models.CharField(max_length=250) 

    objects = InventoryManager() 

Dies wird ein balance Attribut zu Ihrem Inventory Modellinstanzen hinzufügen, wenn sie den Standardmanager retreived verwenden.

Das Problem mit diesem Ansatz (wie in der verknüpften Django-Entwickler-Thread diskutiert) ist, was Ihre Erwartungen sind, wenn Modals lokal geändert werden.

Zum Beispiel mit den Custom-Managern an Ort und Stelle, wenn ich stock_in für ein modalen zu ändern, würde der Wert von total noch für den Wert von stock_in zur Zeit aus der Datenbank des Abrufens gültig:

>> qs = Inventory.objects.filter(date__gte=date(2017, 12, 22)) 
>> inventory0 = qs[0] 
>> print(inventory0.total, inventory0.stock_in, inventory.balance) 
100, 50, 50 
>> inventory.balance = 100 
>> print(inventory0.total, inventory0.stock_in, inventory.balance) 
100, 50, 100 

auch eine Modellinstanz nicht abgerufen aus dem db überhaupt gewohnt haben ein total Attribut:

>> inventory = Inventory(stock_in=20, balance=10) 
>> inventory.total 
AttributeError: 'Inventory' object has no attribute 'total' 

eine __getattr__ Methode Ihrer Klasse hinzufügen könnte b Dies ist eine Lösung für diesen Anwendungsfall, führt jedoch immer noch zu falschen Antworten mit lokalen Änderungen.

Verwandte Themen