Seite 1 von 1

Django: ForeignKey mit 0 als None ?

Verfasst: Dienstag 18. September 2012, 09:52
von jens
phpBB speichert leider beim "leeren" ForeignKey kein None bzw. DB-Null, sondern die Zahl 0

Wie kann ich in Django ein eigene ForeignKey Klasse implementieren, die das akzeptiert? Denn das ORM versucht halt den ForeignKey mit der ID == 0 zu holen, die es natürlich nicht gibt.

Ich hab es so probiert:

Code: Alles auswählen

class PhpBBForeignKey(models.ForeignKey):
    def to_python(self, value):
        if value in ("", None, 0):
            return None
        return super(PhpBBForeignKey, self).to_python(value)

    def get_db_prep_save(self, value, connection):
        if value in ("", None, 0):
            return None
        return super(PhpBBForeignKey, self).get_db_prep_save(value, connection)
Das bringt es allerdings nicht ganz.

Re: Django: ForeignKey mit 0 als None ?

Verfasst: Dienstag 18. September 2012, 10:10
von jens
Denke ich hab eine Lösung gefunden, mit einem eigenen ReverseSingleRelatedObjectDescriptor:

Code: Alles auswählen

class PhpBBReverseSingleRelatedObjectDescriptor(models.fields.related.ReverseSingleRelatedObjectDescriptor):
    def __get__(self, instance, instance_type=None):
        if instance is None:
            return self

        try:
            return getattr(instance, self.cache_name)
        except AttributeError:
            val = getattr(instance, self.field.attname)
            if val in (0, None, ""):
                return None

        return super(PhpBBReverseSingleRelatedObjectDescriptor, self).__get__(instance, instance_type)


class PhpBBForeignKey(models.ForeignKey):
    def to_python(self, value):
        if value in ("", None, 0):
            return None
        return super(PhpBBForeignKey, self).to_python(value)

    def get_db_prep_save(self, value, connection):
        if value in ("", None, 0):
            return None
        return super(PhpBBForeignKey, self).get_db_prep_save(value, connection)

    def contribute_to_class(self, cls, name):
        super(PhpBBForeignKey, self).contribute_to_class(cls, name)
        setattr(cls, self.name, PhpBBReverseSingleRelatedObjectDescriptor(self))
Anmerkungen? Geht das einfacher?

Re: Django: ForeignKey mit 0 als None ?

Verfasst: Dienstag 18. September 2012, 20:22
von apollo13
Ernsthaft? "UPDATE table SET fk=NULL WHERE fk=0"

Re: Django: ForeignKey mit 0 als None ?

Verfasst: Mittwoch 19. September 2012, 09:07
von Leonidas
apollo13 hat geschrieben:Ernsthaft? "UPDATE table SET fk=NULL WHERE fk=0"
+1. Verstehe auch nicht warum man das schlechte phpBB-DB-Layout in ein djangoBB-DB-Layout übernehmen sollte.

Re: Django: ForeignKey mit 0 als None ?

Verfasst: Donnerstag 20. September 2012, 08:33
von jens
Weil django-phpBB die bestehenden Daten am besten nicht ändern sollte. Es geht bei dem Projekt nicht nur um die einmalige Migration (Wobei das mein persönliches Hauptanliegen ist)... Vielmehr sollte man django-phpBB auch dazu nutzen können, parallel auf die Daten zugreifen zu können.

Re: Django: ForeignKey mit 0 als None ?

Verfasst: Donnerstag 20. September 2012, 10:19
von Leonidas
Das finde ich ist ein sinnloser Usecase, wenn man dadurch unnötig die Komplexität des Codes erhöht. Wer will denn phpBB und DjangoBB gleichzeitig betreiben?