2010-06-26 3 views
13

[Update: Changed Frage Titel um genauer zu sein]Wie man ein Auto-gefüllt und Feld mit automatischer Erhöhung in django Admin

Sorry, wenn ich die Frage nicht sehr gut gemacht habe, kann ich‘ t Figur, wie dies zu tun:

class WhatEver(): 
    number = model.IntegerField('Just a Field', default=callablefunction) 
... 

Wo callablefunction hat diese Abfrage:

from myproject.app.models import WhatEver 

def callablefunction(): 
    no = WhatEver.objects.count() 
    return no + 1 

ich möchte automatisch die nächste Nummer schreiben, ein Und ich weiß nicht, wie ich es machen soll.

Ich habe Fehler von callablefunction besagt, dass es das Modell nicht importieren kann, und ich denke, es muss eine einfachere Möglichkeit, dies zu tun. Es gibt keine Notwendigkeit, dies zu verwenden, aber ich kann mir nicht vorstellen, wie es mit der PK-Nummer gemacht wird.

Ich habe über diese gegoogelt und das einzige, was ich war, die save() Methode für die automatische Erhöhen der Anzahl verwenden gefunden ... aber ich wollte es in der <textfield> vor dem Speichern zeigen ...

Was würden Sie tun?

Antwort

19

Verstanden! Ich hoffe, dass dies jedem helfen wird, der Probleme hat, ein automatisch gefülltes und automatisch inkrementierendes Feld in django zu erstellen. Die Lösung lautet:

class Cliente(models.Model): 
    """This is the client data model, it holds all client information. This 
     docstring has to be improved.""" 
    def number(): 
     no = Cliente.objects.count() 
     if no == None: 
      return 1 
     else: 
      return no + 1 

    clientcode = models.IntegerField(_('Code'), max_length=6, unique=True, \ 
    default=number) 

    [... here goes the rest of your model ...] 

Nehmen Sie in der Pflege:

  • Die number Funktion keine Argumente nehmen (nicht einmal selbst)
  • Es VOR alles im Modell geschrieben
  • Dies wurde auf Django 1.2.1 getestet

Dieser Spaß ction füllt automatisch das Feld clientcode mit der nächsten Nummer (d. h.Wenn Sie 132 Kunden haben, wenn Sie die nächste hinzufügen, wird das Feld mit clientcode Nummer 133)

Ich weiß, dass dies absurd für die meisten praktischen Situationen ist, da die PK-Nummer ist auch automatisch inkrementieren, aber Es gibt keine Möglichkeit, den Django-Admin automatisch zu füllen oder praktisch zu nutzen.

[Update: wie ich in meinem Kommentar erwähnte, gibt es eine Möglichkeit gibt, den Primärschlüssel für diese zu verwenden, aber es wird das Feld vor Speicher nicht füllen]

+5

Sind Sie sicher, dass dieser Code auch mit gleichzeitigen Transaktionen funktioniert? Was passiert, wenn zwei Anfragen gleichzeitig "count()" ausführen und später denselben Wert schreiben? – vdboor

+0

Das ist wahr ... in meinem Anwendungsfall spielt es keine Rolle, weil es nie zwei Anfragen gleichzeitig geben wird ... aber selbst dann muss ich einen besseren Weg finden, dies zu implementieren. Danke für den Hinweis! :) –

+0

Ich war in der Lage, etwas ähnliches zu tun, was ich dieses Feld machen möchte: 'id = models.IntegerField (primary_key = True, leer = True)' Das einzige Ding ist, dass es nicht automatisch gefüllt wird, aber das Problem löst von simultanen Anfragen (glaube ich) –

6

Jedes Django Modell verfügt bereits über ein auto-generated primary key:

id = models.AutoField(primary_key=True) 

Es scheint, dass Sie versuchen, ein bereits vorhandenes Verhalten zu duplizieren, nur das Schlüsselobjekt primäre verwenden.

+0

Ich weiß über Primärschlüssel, aber ich muss diese Nummer in der Django-Admin-Seite zeigen. Gibt es eine Möglichkeit, das zu tun? –

+0

Siehe http://stackoverflow.com/questions/2531762/edit-show-primary-key-in-django-admin –

+0

Das funktioniert nicht. Wenn Sie es als AutoField setzen, stürzt django ab. Und wenn es ein IntegerField ist, funktioniert es nicht wie erwartet. Es wird nur ein normales IntegerField. Ich brauche dieses Feld, um mit der nächsten Zahl automatisch gefüllt zu werden (ich denke, ich bin sehr schlecht, mich zu erklären) –

0

Sie haben Fehler im Code, das ist, warum Sie es nicht importieren können:

from django.db import models 
class WhatEver(models.Model): 
    number = models.IntegerField('Just a Field', default=0) 

und Yuval A ist direkt über Auto-Inkrementierung: Sie haben nicht einmal ein solches Feld deklarieren müssen. Verwenden Sie einfach die pk oder id, sie das gleiche bedeuten, es sei denn, es in dem Modell eine Verbund pk ist:

> w = Whatever(number=10) 
> w 
<Whatever object> 
> w.id 
None 
> w.save() 
> w.id 
1 

[Update] Nun, ich habe eine aufrufbare als Standard nicht versucht. Ich denke, wenn Sie diese Fehler beheben, muss es funktionieren.

+0

Ich denke wie für Django 1.2.1 Field.default() kann ein Callable-Objekt, anstatt nur eine Zahl/String haben –

6

Auch ich über dieses Problem kam, meine Instanz davon war customer.number, die relativ zu den Kunden Store war.

# Don't do this: 

class Customer(models.Model): 
    # store = ... 
    number = models.IntegerField(default=0) 

    def save(self, *args, **kwargs): 
     if self.number == 0: 
      try: 
       self.number = self.store.customer_set.count() + 1 
      else: 
       self.number = 1 
     super(Customer, self).save(*args, **kwargs) 

Das Obige kann verursachen mehrere Probleme: Ich war so etwas wie zu verwenden versucht sagen, dass es 10 Kunden waren, und ich gelöscht Kundennummer 6. Der nächste Kunde (scheinbar) würde hinzugefügt werden, um den zehnten Kunde, der dann ein zweiter Kunde # 10 werden würde. (Dies könnte große Fehler in get() querysets verursachen)

Was ich am Ende mit etwas wie:

class Store(models.Model): 
    customer_number = models.IntegerField(default=1) 

class Customer(models.Model): 
    store = models.ForeignKey(Store) 
    number = models.IntegerField(default=0) 

    def save(self, *args, **kwargs): 
     if self.number == 0: 
      self.number = self.store.customer_number 
      self.store.number += 1 
      self.store.save() 
     super(Customer, self).save(*args, **kwargs) 

PS:

Sie mehrmals warf, dass Sie dieses Feld in "gefüllt wollte vor ". Ich stelle mir vor, Sie wollten es vor dem Speichern ausgefüllt haben, damit Sie darauf zugreifen können. Dazu würde ich sagen: Mit dieser Methode können Sie auf store.customer_number zugreifen, um die nächste Nummer zu sehen.

+0

Obwohl dies das doppelte Problem lösen wird, aber immer noch Lücken vorhanden sind, wenn ich einen Eintrag dazwischen lösche. Kann nicht als Indexnummer für Tupel in der Tabelle verwendet werden. –

+0

Gibt es eine Möglichkeit, Zahlen so zu generieren, dass sie Continuos sind und der Wert der letzten Zahl gleich 'count()' ist. Alle Zahlen sollten aktualisiert werden, wenn ein Eintrag gelöscht wird?Ich nehme an, dies kann Delete Event Detection getan werden und eine Schleife verwenden, um alle Einträge zu aktualisieren. Aber ich weiß nicht, wie dies in Django-Modellen zu tun ist. Sie können Ihren Code bearbeiten, um dieses Problem zu lösen .. –

+2

Die Methode, die ich gemacht wie Auto-Inkrement tut, wie in, es Nummern nicht wiederverwenden. Du könntest eine Schleife schreiben, um die Zahlen zu aktualisieren, aber es ist wahrscheinlich nicht die Zeit wert, um diese Funktion zu schreiben, und die [Computer] -Zeit, um sie auszuführen, ist es nicht wert. Selbst mit einer kleinen Datenbank könnte die Zeit, alle diese Daten zu erfassen, enorm sein. –

Verwandte Themen