.save() in django model __init__() benutzen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
d3f3nd3r
User
Beiträge: 40
Registriert: Montag 19. November 2007, 20:17

Sonntag 20. Januar 2008, 19:48

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
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Sonntag 20. Januar 2008, 19:53

Du kannst __init__ für django Modelle nicht überladen.
TUFKAB – the user formerly known as blackbird
d3f3nd3r
User
Beiträge: 40
Registriert: Montag 19. November 2007, 20:17

Sonntag 20. Januar 2008, 20:02

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...
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Sonntag 20. Januar 2008, 20:13

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...
d3f3nd3r
User
Beiträge: 40
Registriert: Montag 19. November 2007, 20:17

Sonntag 20. Januar 2008, 20:53

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
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 20. Januar 2008, 21:29

Das würde man mit Validatoren lösen. Guck mal hier.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Sonntag 20. Januar 2008, 22:34

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
Antworten