django: ModelForm vom django 'User' model.

Django, Flask, Bottle, WSGI, CGI…
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Seit neustem hab ich damit Probleme:

Code: Alles auswählen

from django.contrib.auth.models import User
class UsernameForm(forms.ModelForm):
    class Meta:
        model = User
        fields=("username",)
Wenn das Formular abgeschickt wird, gibt es immer nur ein Form-Error:
User with this Username already exists.
Weiß jemand warum?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Bin nur ein kleines Stück weiter. Es hat was zu tun mit der Änderung: http://code.djangoproject.com/changeset/8805
Mit django.models.BaseModelForm.validate_unique() dort wird der Fehler erzeugt.

Hab mal eine locale Test App gebaut:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os

os.chdir("../pylucid_project/") # Goto where django exist, optional

APP_LABEL = os.path.splitext(os.path.basename(__file__))[0]

os.environ["DJANGO_SETTINGS_MODULE"] = "django.conf.global_settings"
from django.conf import global_settings

global_settings.INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    APP_LABEL,
)
global_settings.DATABASE_ENGINE = "sqlite3"
global_settings.DATABASE_NAME = ":memory:"

#______________________________________________________________________________
# Test app code:

from django import forms
from django.contrib.auth.models import User
class UsernameForm(forms.ModelForm):
    class Meta:
        model = User
        fields=("username",)

#------------------------------------------------------------------------------
if __name__ == "__main__":
    print "- create the model tables...",
    from django.core import management
    management.call_command('syncdb', verbosity=1, interactive=False)
    print "OK"

    #__________________________________________________________________________
    # Test code:
     
    User.objects.create_superuser(username="test", email="", password="test")
    
    f = UsernameForm({u'username': u'test'})
    print f.is_valid()
    print f.errors
    
    print "- END -"
Ausgabe (Auf's wesentliche gekürzt):
...
False
...User with this Username already exists...
...
Es ist also so, das es normal ist?

EDIT: Code korrigiert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So. Also ich denke ich hab das Problem gefunden: ModelForms sind dazu da, die POST Daten auch wirklich in das entsprechende Datenbankmodel einzufügen.
In meinem Fall möchte ich aber ModelForms nur dazu nutzten, die Form zu generieren und die Daten zu validieren: z.B. Ist der eingegebene Username ok? Ich möchte aber nicht den User anlegen. Somit braucht validate_unique() nicht ausgeführt werden. Ich sehe im django code aber keine Möglichkeit das auszuschalten.

Übersehe ich da etwas?

EDIT: gerade eine Idee, siehe:

Code: Alles auswählen

class UsernameForm(forms.ModelForm):

    def validate_unique(self):
        """ nicht unique testen """
        pass

    class Meta:
        model = User
        fields=("username",)
Damit wird das Prüfen komplett "übersprungen"...

EDIT: Siehe auch http://www.jensdiemer.de/_command/118/blog/detail/30/

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Schade... validate_unique() überschreiben hilft mit dem aktuellen django trunk nicht mehr :(

Jemand eine Idee?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

jens hat geschrieben:Jemand eine Idee?
Eine normale Form selbst bauen?

Stefan
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

+1, ein ModelForm für ein Feld, wo man nur den Username eingeben kann und nichtmal den validieren will ist sinnfrei…
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das ganze ist für einen eigenen Login view. Ich brauche mal den Usernamen, mal das password und mal die email Adresse.

Und natürlich sollte die Form validiert werden. z.B. die Länge der Eingabe. Eine ModelForm bietet sich da an, weil man dann automatisch die Sachen vom bestehenden Model übernimmt.

Aber wahrscheinlich ist es wirklich einfacher eine normale Form selber zu erstellen. Aber richtig DRY ist das nicht...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Nunja es ist weiterhin DRY; du brauchst nur die Modelvalidation für das Feld username deaktivieren (Die nun eben im Model selbst gemacht wird, aber vom Form aus deaktiviert werden kann…).
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Äh?

Also wenn ich eine eigene Form erstelle, dann habe ich keine Verbindung zum Model.

Wenn ich eine ModelForm erstelle, dann schon. Aber wie deaktiviere ich die model validation da?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

jens hat geschrieben:Wenn ich eine ModelForm erstelle, dann schon. Aber wie deaktiviere ich die model validation da?
Use the source luke! Sollte nach anschauen von ModelForm.clean eigentlich glasklar sein… Allerdings musst du probieren, ob die max_length dann nicht auch gleich übersprungen wird…
Antworten