Ricerca…


Esempio ModelForm

Creare un ModelForm da una classe Model esistente, sottoclasse ModelForm :

from django import forms

class OrderForm(forms.ModelForm):
    class Meta:
        model = Order
        fields = ['item', 'order_date', 'customer', 'status']

Definire una forma di Django da zero (con i widget)

Le forme possono essere definite, in modo simile ai modelli, sottoclassando django.forms.Form .
Sono disponibili varie opzioni di input sul campo, come CharField , URLField , IntegerField , ecc.

Di seguito è riportato un semplice modulo di contatto:

from django import forms

class ContactForm(forms.Form):
    contact_name = forms.CharField(
        label="Your name", required=True,
        widget=forms.TextInput(attrs={'class': 'form-control'}))
    contact_email = forms.EmailField(
        label="Your Email Address", required=True,
        widget=forms.TextInput(attrs={'class': 'form-control'}))
    content = forms.CharField(
        label="Your Message", required=True,
        widget=forms.Textarea(attrs={'class': 'form-control'}))

Widget è la rappresentazione di Django dei tag di input dell'utente HTML e può essere utilizzato per il rendering di html personalizzato per i campi del modulo (ad esempio: come una casella di testo viene renderizzata per l'input del contenuto qui)

attrs sono attributi che verranno copiati così come lo sono per l'html renderizzato per il modulo.

Ad esempio: content.render("name", "Your Name")

<input title="Your name" type="text" name="name" value="Your Name" class="form-control" />

Rimozione di un campo modelForm in base alle condizioni di views.py

Se abbiamo un modello come segue,

from django.db import models
from django.contrib.auth.models import User

class UserModuleProfile(models.Model):
    user = models.OneToOneField(User)
    expired = models.DateTimeField()
    admin = models.BooleanField(default=False)
    employee_id = models.CharField(max_length=50)
    organisation_name = models.ForeignKey('Organizations', on_delete=models.PROTECT)
    country = models.CharField(max_length=100)
    position = models.CharField(max_length=100)

    def __str__(self):
        return self.user

E un modello che utilizza questo modello come segue,

from .models import UserModuleProfile, from django.contrib.auth.models import User
from django import forms

class UserProfileForm(forms.ModelForm):
    admin = forms.BooleanField(label="Make this User Admin",widget=forms.CheckboxInput(),required=False)
    employee_id = forms.CharField(label="Employee Id ")
    organisation_name = forms.ModelChoiceField(label='Organisation Name',required=True,queryset=Organizations.objects.all(),empty_label="Select an Organization")
    country = forms.CharField(label="Country")
    position = forms.CharField(label="Position")

    class Meta:
        model = UserModuleProfile
        fields = ('admin','employee_id','organisation_name','country','position',)

    def __init__(self, *args, **kwargs):
        admin_check = kwargs.pop('admin_check', False)
        super(UserProfileForm, self).__init__(*args, **kwargs)
        if not admin_check:
            del self.fields['admin']

Si noti che sotto la classe Meta nel modulo ho aggiunto una funzione init che possiamo usare durante l'inizializzazione del modulo da views.py per eliminare un campo modulo (o alcune altre azioni). Lo spiegherò più tardi.

Quindi questo modulo può essere utilizzato per scopi di registrazione dell'utente e vogliamo tutti i campi definiti nella classe Meta del modulo. Ma cosa succede se vogliamo utilizzare lo stesso modulo quando modifichiamo l'utente, ma quando lo facciamo non vogliamo mostrare il campo admin del modulo?

Possiamo semplicemente inviare un argomento aggiuntivo quando inizializziamo il modulo in base ad una logica e cancelliamo il campo admin dal backend.

def edit_profile(request,user_id):
    context = RequestContext(request)
    user = get_object_or_404(User, id=user_id)
    profile = get_object_or_404(UserModuleProfile, user_id=user_id)
    admin_check = False
    if request.user.is_superuser:
        admin_check = True
    # If it's a HTTP POST, we're interested in processing form data.
    if request.method == 'POST':
        # Attempt to grab information from the raw form information.
        profile_form = UserProfileForm(data=request.POST,instance=profile,admin_check=admin_check)
        # If the form is valid...
        if profile_form.is_valid():
            form_bool = request.POST.get("admin", "xxx")
            if form_bool == "xxx":
                form_bool_value = False
            else:
                form_bool_value = True
            profile = profile_form.save(commit=False)
            profile.user = user
            profile.admin = form_bool_value
            profile.save()
            edited = True
        else:
            print profile_form.errors

    # Not a HTTP POST, so we render our form using ModelForm instance.
    # These forms will be blank, ready for user input.
    else:
        profile_form = UserProfileForm(instance = profile,admin_check=admin_check)

    return render_to_response(
            'usermodule/edit_user.html',
            {'id':user_id, 'profile_form': profile_form, 'edited': edited, 'user':user},
            context)

Come puoi vedere ho mostrato qui un semplice esempio di modifica usando il modulo che abbiamo creato in precedenza. Nota che quando ho inizializzato il modulo ho passato una variabile admin_check aggiuntiva che contiene True o False .

profile_form = UserProfileForm(instance = profile,admin_check=admin_check)

Ora Se noti il ​​modulo che abbiamo scritto in precedenza puoi vedere che in init proviamo a catturare il parametro admin_check che passiamo da qui. Se il valore è False, semplicemente eliminiamo il campo admin dal modulo e lo usiamo. E poiché questo è un modello di modulo, il campo admin non può essere nullo nel modello, controlliamo semplicemente se il post del modulo ha il campo admin nel post del modulo, altrimenti lo impostiamo su False nel codice della vista nel seguente codice della vista.

form_bool = request.POST.get("admin", "xxx")
if form_bool == "xxx":
    form_bool_value = False
else:
    form_bool_value = True

Upload di file con Django Forms

Prima di tutto dobbiamo aggiungere MEDIA_ROOT e MEDIA_URL al nostro file settings.py

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

Anche qui lavorerai con ImageField , quindi ricorda di installare in questo caso la libreria Pillow ( pip install pillow ). In caso contrario, si avrà tale errore:

ImportError: No module named PIL

Pillow è un fork di PIL, la Python Imaging Library, che non viene più mantenuta. Il cuscino è retrocompatibile con PIL.

Django viene fornito con due campi modulo per caricare file sul server, FileField e ImageField , il seguente è un esempio di utilizzo di questi due campi nel nostro modulo

forms.py:

from django import forms


class UploadDocumentForm(forms.Form):
    file = forms.FileField()
    image = forms.ImageField()

views.py:

from django.shortcuts import render
from .forms import UploadDocumentForm


def upload_doc(request):
    form = UploadDocumentForm()
    if request.method == 'POST':
        form = UploadDocumentForm(request.POST, request.FILES)  # Do not forget to add: request.FILES
        if form.is_valid():
            # Do something with our files or simply save them
            # if saved, our files would be located in media/ folder under the project's base folder
            form.save()
    return render(request, 'upload_doc.html', locals())

upload_doc.html:

<html>
    <head>File Uploads</head>
    <body>
        <form enctype="multipart/form-data" action="" method="post"> <!-- Do not forget to add: enctype="multipart/form-data" -->
            {% csrf_token %}
            {{ form }}
            <input type="submit" value="Save">
        </form>
    </body>
</html>

Convalida dei campi e impegno per modellare (Modifica e-mail utente)

Ci sono già moduli implementati in Django per cambiare la password dell'utente, un esempio è SetPasswordForm .

Non ci sono, tuttavia, moduli per modificare l'e-mail dell'utente e penso che il seguente esempio sia importante per capire come utilizzare correttamente un modulo.

L'esempio seguente esegue i seguenti controlli:

  • Le e-mail sono infatti cambiate - molto utili se è necessario convalidare l'e-mail o aggiornare la posta scimpanzè;
  • Sia l'e-mail sia l'e-mail di conferma sono le stesse: il modulo ha due campi per l'e-mail, quindi l'aggiornamento è meno soggetto a errori.

E alla fine, salva la nuova e-mail nell'oggetto utente (aggiorna l'e-mail dell'utente). Si noti che il metodo __init__() richiede un oggetto utente.

class EmailChangeForm(forms.Form):
    """
    A form that lets a user change set their email while checking for a change in the 
    e-mail.
    """
    error_messages = {
        'email_mismatch': _("The two email addresses fields didn't match."),
        'not_changed': _("The email address is the same as the one already defined."),
    }

    new_email1 = forms.EmailField(
        label=_("New email address"),
        widget=forms.EmailInput,
    )

    new_email2 = forms.EmailField(
        label=_("New email address confirmation"),
        widget=forms.EmailInput,
    )

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(EmailChangeForm, self).__init__(*args, **kwargs)

    def clean_new_email1(self):
        old_email = self.user.email
        new_email1 = self.cleaned_data.get('new_email1')
        if new_email1 and old_email:
            if new_email1 == old_email:
                raise forms.ValidationError(
                    self.error_messages['not_changed'],
                    code='not_changed',
                )
        return new_email1

    def clean_new_email2(self):
        new_email1 = self.cleaned_data.get('new_email1')
        new_email2 = self.cleaned_data.get('new_email2')
        if new_email1 and new_email2:
            if new_email1 != new_email2:
                raise forms.ValidationError(
                    self.error_messages['email_mismatch'],
                    code='email_mismatch',
                )
        return new_email2

    def save(self, commit=True):
        email = self.cleaned_data["new_email1"]
        self.user.email = email
        if commit:
            self.user.save()
        return self.user



def email_change(request):
    form = EmailChangeForm()
    if request.method=='POST':
        form = Email_Change_Form(user,request.POST)
        if form.is_valid():
            if request.user.is_authenticated:
                if form.cleaned_data['email1']  == form.cleaned_data['email2']:
                    user = request.user
                    u = User.objects.get(username=user)
                    # get the proper user
                    u.email = form.cleaned_data['email1'] 
                    u.save()
                    return HttpResponseRedirect("/accounts/profile/")
    else:
        return render_to_response("email_change.html", {'form':form},
                                   context_instance=RequestContext(request))


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow