News

Piccolo contributo per rinnovo abbonamento hosting: http://www.python-it.org/forum/index.php?topic=10331.0

Topic: Sign up in django  (Letto 259 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline DragLag

  • python habilis
  • **
  • Post: 57
  • Punti reputazione: 0
    • Mostra profilo
    • mirkosecke
Sign up in django
« il: Marzo 29, 2017, 11:32 »
Ciao a tutti

Starei provando a metter giu un semplice modulo di django per la gestione utenti.

Avrei un problema...

forms.py

class SignupForm(forms.Form):
    username = forms.CharField(label='Your username', max_length=100)
    email = forms.EmailField(help_text='A valid email address, please.')
    name = forms.CharField(max_length=32)
    surname = forms.CharField(max_length=32)
    password = forms.CharField(max_length=32, widget=forms.PasswordInput)
    retype_password = forms.CharField(max_length=32, widget=forms.PasswordInput)  #dovrebbe essere default "required = True" quindi non puo accettare stringhe vuote. In effetti non posso inserirle...
   
    def clean_password(self):
        password = self.cleaned_data.get('password')
        retype_password = self.cleaned_data.get('retype_password') #cosi non funziona
        print(password)                #riporta correttamente la password inserisca
        print(retype_password) #non riporta la password inserita. None per ogni valore inserito. 
        if not retype_password:
            raise forms.ValidationError("You must confirm your password")
        if password != retype_password:
            raise forms.ValidationError("Your passwords do not match")
        return retype_password
   
    def insert_user(self):
        password = self.clean_password()
        query = User(
                    username = self.cleaned_data.get('username'),
                    email = self.cleaned_data.get('email'),
                    first_name = self.cleaned_data.get('name'),
                    last_name = self.cleaned_data.get('surname'),
                    password = make_password('password')
                    )
        query.save()



view.py

def signup(request):
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            try:#insersci in db
                print (form.cleaned_data) #stampa correttamente tutti i valori del form...
                form.insert_user()
                messages.info(request, 'thank you. now you can log in')
                return HttpResponseRedirect('/users/login')
            except Exception as e:
                print (e)
                return HttpResponse("somthing wrong processing data.")
        else:
           return HttpResponse("form not valide.")
    else:
        form = SignupForm()
        return render (request ,"users/signup.html", {'form' : form})



starei cercando di validare la password. ma non capisco perche "retype_password" non viene ripreso dal metodo clean_password .

Se avete consigli o suggerimenti per migliorare il codice vi ringrazio in anticipo.
« Ultima modifica: Marzo 30, 2017, 17:45 da DragLag »

Online RicPol

  • python sapiens sapiens
  • ******
  • Post: 2567
  • Punti reputazione: 9
    • Mostra profilo
Re:Sign up in django
« Risposta #1 il: Marzo 29, 2017, 13:33 »
Se tutte le volte che scrivete "non funziona" la tastiera vi mandasse una scarica elettrica bella secca (ma proprio bella secca, eh), non sarebbe più semplice che dovervelo ricordare tutte le volte?

Ora, capisco che gli stacktrace di django sono chilometrici, ma davvero, almeno darci un indizio sul
C H E  C O S A
"non funziona", non renderebbe le cose un poco più facili e veloci?
Specialmente in django, dove la black magic al lavoro è sempre tantissima, ed è veramente difficile divinare le cose senza avere informazioni.

Ora, la butto così a caso: non è magari che, al momento di validare "password", "retype_password" non sia ancora stata validata, e quindi non esiste ancora "cleaned_data[retype_password]"? Se è così, dovresti avere un errore equivalente a un KeyError su un dizionario (magari avvolto in strati e strati di complicato stacktrace di django... ma insomma, il succo sarebbe quello). Potrei sbagliarmi, ma senza sapere che cosa non funziona... boh.

E comunque in ogni caso: che cosa c'è che non ti piace in django.contrib.auth che devi reinventare daccapo la ruota?

Offline DragLag

  • python habilis
  • **
  • Post: 57
  • Punti reputazione: 0
    • Mostra profilo
    • mirkosecke
Re:Sign up in django
« Risposta #2 il: Marzo 30, 2017, 13:52 »
Parlando fra persone e non fra computer la comunicazione non e sempre, come dire, "oggettiva".

Quel che e chiaro per te potrebbe non essere chiaro per me.

Per quello l idea della "scossa" non sarebbe cosi semplice da implementare. Difficile dire quando e bianco o nero.

Comunque...

Stampando i valori i password e retype_password da clean_password ottengo


password= xxx
retype_password = None


Per python credo che questo non sia un errore.  Semplicemente non funziona come vorrei.

Non e che non mi piace... Il modulo django.contrib.auth ha anche un metodo per validare la password?... so che viene impiegato per autenticare gli utenti.
Googlando vedo che si trovano solo soluzioni che implementano un metodo nella classe del form per validare la password.
Sulla documentazione non l ho trovato.

Ti ringrazio, comunque nessun KeyError


Online RicPol

  • python sapiens sapiens
  • ******
  • Post: 2567
  • Punti reputazione: 9
    • Mostra profilo
Re:Sign up in django
« Risposta #3 il: Marzo 30, 2017, 14:59 »
> Parlando fra persone e non fra computer la comunicazione non e sempre, come dire, "oggettiva".

Sì ma parlando DI computer, anche tra umani, varrebbe la pena di cercare di essere oggettivi. Cioè, supponendo che tu voglia risolvere i tuoi problemi in modo più rapido e più corretto, beninteso. Ma si tratta dei tuoi problemi, quindi non saprei dire.

> Quel che e chiaro per te potrebbe non essere chiaro per me.

No, no, non stiamo parlando di metafisica o di psicologia qui. Come detto (da me e da altri, su questo forum e su migliaia di altri forum) quando si trova "qualcosa che non va" si deve descrivere nel dettaglio CHE COSA non va. Codice, condizioni al contorno, input, output, errori. Poi magari si trascura qualcosa di essenziale, ma di sicuro non si resta fermi al "non funziona".


> Stampando i valori i password e retype_password da clean_password ottengo ...

Eccola lì... visto che non era poi così difficile descrivere le cose con un po' più di dettaglio?
Purtroppo però non basta ancora... Un problema è che non si capisce _quando_ stampi questi valori: è il risultato di quel print che vedo alla riga 6 di view.py? Se è così, allora non è chiaro se ottieni un None quando è attiva la riga 10 o la riga 11 di forms.py... E che cosa hai scritto davvero nel campo retype_password?  O lo hai lasciato in bianco? Cioè, quel None dice la verità o è sbagliato rispetto a quello che il campo contiene?
Prova a metterti lì e spiegare bene tutto quanto. Se vuoi. Altrimenti non importa.

> Per python credo che questo non sia un errore.
Eh no, tecnicamente no. Specialmente se in effetti quel campo lo hai lasciato vuoto. Ma da come la racconti mi sembra sempre di più un problema di ordine della validazione. Non posso dire di più, con i dati che ho.  Poi magari qualcuno più bravo di me con django ha già capito tutto... non saprei.

> Non e che non mi piace... Il modulo django.contrib.auth ha anche un metodo per validare la password?
Mah, mi stupirebbe se non ci fosse qualcosa. E comunque puoi sempre aggiungere partendo da qualcosa di solido e ben testato, invece di farti tutto a mano.


EDIT: sì, ho dato una scorsa alla documentazione e in effetti pare proprio che esista un form che fa questa cosa. Potresti magari dare un'occhiata al sorgente e vedere come fa...
« Ultima modifica: Marzo 30, 2017, 15:07 da RicPol »

Offline DragLag

  • python habilis
  • **
  • Post: 57
  • Punti reputazione: 0
    • Mostra profilo
    • mirkosecke
Re:Sign up in django
« Risposta #4 il: Marzo 30, 2017, 18:08 »
ho modificato gli script del topic... ora dovrebbero essere piu chiaro. Almeno spero

Comunque non era mia intenzione essere non chiaro, anzi.
Ero convinto di esserlo ma mi sbagliavo... ma ero in buona fede , te lo giuro! :angel: :D

or dunque...

Citazione
Eccola lì... visto che non era poi così difficile descrivere le cose con un po' più di dettaglio?
Purtroppo però non basta ancora... Un problema è che non si capisce _quando_ stampi questi valori: è il risultato di quel print che vedo alla riga 6 di view.py? Se è così, allora non è chiaro se ottieni un None quando è attiva la riga 10 o la riga 11 di forms.py... E che cosa hai scritto davvero nel campo retype_password?  O lo hai lasciato in bianco? Cioè, quel None dice la verità o è sbagliato rispetto a quello che il campo contiene?

L ho riportato sullo script, cmq stampa None per ogni stringa. Il campo non puo essere una stringa vuota in quando e un campo richiesto dal form.

Citazione
Mah, mi stupirebbe se non ci fosse qualcosa. E comunque puoi sempre aggiungere partendo da qualcosa di solido e ben testato, invece di farti tutto a mano.
si certo che ci sono. Solo che purtroppo molti fanno uso di funzionalita quali "super" e  "meta". Mi chiedevo se potevo creare qualcosa alla mia portata per poi ampliare piano piano.  Sto imparando cosi...
e cmq non e tutta farina del mio sacco:
http://stackoverflow.com/questions/3226197/why-is-checking-if-two-passwords-match-in-django-so-complicated
ma almeno riesco a comprenderla...

Potresti inviarmi il link della documentazione che hai visto?

Ti ringrazio per l 'aiuto!


Offline DragLag

  • python habilis
  • **
  • Post: 57
  • Punti reputazione: 0
    • Mostra profilo
    • mirkosecke
Re:Sign up in django
« Risposta #5 il: Marzo 31, 2017, 09:51 »
Risolto...

Al posto di

def clean_password(self):


ho inserito

 def clean_password2(self):


e funziona preciso...

In effetti nel posto di SO viene riportato clean_password2... a me il 2 non e che piaceva piu di tanto quindi ho pensato bene di toglierlo. Prima di toglierlo pero diedi un occhio alla documentazione se per caso non andavo ad overloadare qualcosa. Non trovai nulla...

bhe a quanto pare ce...

Certo che e difficile orientarsi in tutti i metodi delle classi di django, sono veramente tanti..

 ti ringrazio RicPol!

Online RicPol

  • python sapiens sapiens
  • ******
  • Post: 2567
  • Punti reputazione: 9
    • Mostra profilo
Re:Sign up in django
« Risposta #6 il: Marzo 31, 2017, 10:01 »
EH?!? Mah, sarà... però questo è un hack sicuramente fragilissimo. Se non spendi del tempo per capire PERCHE' adesso funziona e prima no... temo che te lo ritroverai tra i piedi molto presto.
Come ti dicevo, probabilmente il problema sta nel cross-validare il campo B in base al contenuto (validato) del campo A. Siccome non hai modo di sapere l'ordine della validazione (o forse invece un modo c'è, e bisognerebbe leggere con cura la documentazione... va a sapere), non puoi sapere se al momento di validare B tu hai già pronto il risultato della validazione di A.
Questo è un problema tipico dei framework con validazione. In genere c'è il modo di specificare l'ordine della validazione... non saprei in django però. Sono sicuro che cercando qualcosa si trova.

Offline DragLag

  • python habilis
  • **
  • Post: 57
  • Punti reputazione: 0
    • Mostra profilo
    • mirkosecke
Re:Sign up in django
« Risposta #7 il: Marzo 31, 2017, 10:24 »
Per info e completezza forse ci sono:

The clean_<fieldname>() method is called on a form subclass – where <fieldname> is replaced with the name of the form field attribute. This method does any cleaning that is specific to that particular attribute, unrelated to the type of field that it is. This method is not passed any parameters. You will need to look up the value of the field in self.cleaned_data and remember that it will be a Python object at this point, not the original string submitted in the form (it will be in cleaned_data because the general field clean() method, above, has already cleaned the data once).

da qui: https://docs.djangoproject.com/en/1.10/ref/forms/validation/

Ecco perche clean_password non fuzionava...

 def clean_retype_password(self):


dovrebbe essere coerente con il mio form.

Online RicPol

  • python sapiens sapiens
  • ******
  • Post: 2567
  • Punti reputazione: 9
    • Mostra profilo
Re:Sign up in django
« Risposta #8 il: Marzo 31, 2017, 14:32 »
E' possibile, ma se "clean_retype_password" funziona, è solo perché è un altro hack. Fai affidamento sul fatto che "password" è validata _prima_ di "retype_password"... il che può anche essere vero nel tuo caso, e ti auguro di sì. Ma resta un hack.
Non so se c'è un modo più pulito in django di fare cross-validation. Non ho mai avuto bisogno di fare queste cose. Mi faccio un appunto mentale per il futuro, però.