Seite 1 von 1

.save() in django model __init__() benutzen

Verfasst: Sonntag 20. Januar 2008, 19:48
von d3f3nd3r
heo

und wieder eine Frage zum Thema django.

Objektorientierung ist eine tolle Sache, mit Standardkonstruktoren und so weiter, und das noch durch django mit einer Datenbank verbunden (in meinem Fall mysql) ist noch besser.

also wieso keinen Konstruktor für die Datenbankeinträge?

Nur leider funktioniert das nicht so wie ich mir das vorgestellt habe.

Code: Alles auswählen

class Topic(models.Model):  # for tabmenu entries
		name			=  models.CharField(maxlength=60)
		linkname			=  models.CharField(maxlength=20)
		description = models.TextField()
		
		def __init__(self,name,description,linkname):
			self.name = name
			self.linkname = linkname
			self.description = description

			self.save()
			  	
wird der Konstruktor aufgerufen bekomme ich folgender kryptische Fehlermeldung

Code: Alles auswählen

In [3]: CreateDB()
---------------------------------------------------------------------------
exceptions.AttributeError                            Traceback (most recent call last)

/home/d3f3nd3r/Projects/comenius_py/<ipython console> 

/home/d3f3nd3r/Projects/comenius_py/db/init_db.py in CreateDB()
     10         User3 = User("tom","tom","tom@ad.re")
     11 
---> 12         t1 = Topic("Comenius","das Projekt am litec, allgmein","Comenius")
     13 
     14         t2 = Topic("Global Warming","das GLOWA Projekt am litec","GlobalWarming")

/home/d3f3nd3r/Projects/comenius_py/db/models.py in __init__(self, name, description, linkname)
    120                         self.description = description
    121 
--> 122                         self.save()
    123 
    124 class SubTopic(models.Model):  # for tabmenu entries

/var/lib/python-support/python2.4/django/db/models/base.py in save(self)
    201 
    202         # First, try an UPDATE. If that doesn't update anything, do an INSERT.
--> 203         pk_val = self._get_pk_val()
    204         pk_set = bool(pk_val)
    205         record_exists = True

/var/lib/python-support/python2.4/django/db/models/base.py in _get_pk_val(self)
     76 
     77     def _get_pk_val(self):
---> 78         return getattr(self, self._meta.pk.attname)
     79 
     80     def __repr__(self):

AttributeError: 'Topic' object has no attribute 'id'
Irgendwie muss ich die id setzten, weil bei save() muss die id anscheinend schon gesetzt sein.Leider hab in der Django Database API nur herausgefunden, wie ich der id einen bestimmten Wert zuweise aber nicht wie ich im Konstruktor der id einen automatischen wert (auto increment) zuweise.

Hat jemand eine Idee wie ich das Implementieren kann oder ist das nicht möglich?

mfg

Verfasst: Sonntag 20. Januar 2008, 19:53
von mitsuhiko
Du kannst __init__ für django Modelle nicht überladen.

Verfasst: Sonntag 20. Januar 2008, 20:02
von d3f3nd3r
hm das erklärt einiges.....

Hm das mit dem Überladen wäre aber um einiges eleganter als zuerst ein Objekt zu erzeugen und dieses dann mit zb obj.init(arg1,arg2,...) oder so...

Verfasst: Sonntag 20. Januar 2008, 20:13
von apollo13
d3f3nd3r hat geschrieben:hm das erklärt einiges.....

Hm das mit dem Überladen wäre aber um einiges eleganter als zuerst ein Objekt zu erzeugen und dieses dann mit zb obj.init(arg1,arg2,...) oder so...
Andere Frage: Warum willst du __init__ überladen, bzw was willst du darin tun, vlt gibt es einen besseren Weg?

Btw gibt es noch http://www.djangoproject.com/documentat ... ate-kwargs

und
instance = Model(topic=..., ... ) geht eh so schon...

Verfasst: Sonntag 20. Januar 2008, 20:53
von d3f3nd3r
ja nur beim aufruf der save() methode bekomme ich oben genannten error....

und wieso ich einen Konstruktor einsetzen will??

so kann ich zb bei einem neuen user die daten dem Konstruktor übergeben und im Konstruktor die Daten überprüfen(zb Länge des pw, email usw)

ist doch eleganter/mehr im Sinne der Objektorientierung oder?

mfg

Verfasst: Sonntag 20. Januar 2008, 21:29
von Leonidas
Das würde man mit Validatoren lösen. Guck mal hier.

Verfasst: Sonntag 20. Januar 2008, 22:34
von sma
d3f3nd3r, du kannst folgendes auch ohne eigenes `__init__` machen:

Code: Alles auswählen

t1 = Topic(
  name="Comenius",
  linkname="das Projekt am litec, allgmein",
  description="Comenius")
Prüfen, ob die Daten gültig sind, würde ich wie von Löwensohn vorgeschlagen, den Validatoren von Django überlassen.

Stefan