Szukaj…


Przykład ModelForm

Utwórz ModelForm z istniejącej klasy Model, ModelForm :

from django import forms

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

Definiowanie formularza Django od podstaw (z widżetami)

Formularze można zdefiniować w podobny sposób jak modele, django.forms.Form .
Dostępne są różne opcje wprowadzania pól, takie jak CharField , URLField , IntegerField itp.

Zdefiniowanie prostego formularza kontaktowego można zobaczyć poniżej:

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'}))

Widżet jest reprezentacją Django znaczników HTML wprowadzanych przez użytkownika i może być używany do renderowania niestandardowego kodu HTML dla pól formularzy (np .: gdy pole tekstowe jest renderowane dla danych wprowadzanych tutaj)

attrs to atrybuty, które zostaną skopiowane tak jak renderowany HTML dla formularza.

Np .: content.render("name", "Your Name") daje

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

Usuwanie pola modelForm na podstawie warunku z views.py

Jeśli mamy następujący model,

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

I formularz modelowy, który wykorzystuje ten model w następujący sposób,

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']

Zauważ, że poniżej klasy Meta w formularzu dodałem funkcję init, której możemy użyć podczas inicjalizacji formularza z views.py, aby usunąć pole formularza (lub kilka innych akcji). Wyjaśnię to później.

Tak więc ten formularz może być używany do celów rejestracji użytkowników i chcemy, aby wszystkie pola zdefiniowane były w klasie Meta formularza. Ale co, jeśli chcemy używać tego samego formularza podczas edycji użytkownika, ale kiedy tak nie chcemy, aby wyświetlać pole administracyjne formularza?

Możemy po prostu wysłać dodatkowy argument, gdy inicjalizujemy formularz w oparciu o logikę i usuwamy pole administratora z backendu.

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)

Jak widać, pokazałem tutaj prosty przykład edycji z wykorzystaniem formularza, który wcześniej utworzyliśmy. Zauważ, że kiedy zainicjowałem formularz, przekazałem dodatkową zmienną admin_check , która zawiera True lub False .

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

Teraz, jeśli zauważysz formularz, który napisaliśmy wcześniej, zobaczysz, że w init staramy się uchwycić parametr admin_check , który tutaj przekazujemy. Jeśli wartość to Fałsz, po prostu usuwamy pole admin z formularza i używamy go. Ponieważ jest to modelowe pole administratora formularza, które nie może być puste w modelu, po prostu sprawdzamy, czy pole formularza ma pole administracyjne w formularzu formularza, jeśli nie, ustawiamy je na False w kodzie widoku w poniższym kodzie widoku.

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

Przesyłanie plików za pomocą formularzy Django

Przede wszystkim musimy dodać MEDIA_ROOT i MEDIA_URL do naszego pliku settings.py

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

Również tutaj będziesz pracować z ImageField , więc pamiętaj, w takich przypadkach zainstaluj bibliotekę Pillow ( pip install pillow ). W przeciwnym razie wystąpi taki błąd:

ImportError: No module named PIL

Poduszka to rozwidlenie biblioteki PIL, Python Imaging Library, która nie jest już utrzymywana. Poduszka jest wstecznie kompatybilna z PIL.

Django zawiera dwa pola formularza do przesyłania plików na serwer, FileField i ImageField , poniżej znajduje się przykład użycia tych dwóch pól w naszym formularzu

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>

Sprawdzanie poprawności pól i zatwierdzanie do modelu (Zmień adres e-mail użytkownika)

Istnieją już zaimplementowane formularze w Django do zmiany hasła użytkownika, jednym z przykładów jest SetPasswordForm .

Nie ma jednak formularzy do modyfikowania wiadomości e-mail użytkownika i uważam, że poniższy przykład jest ważny, aby zrozumieć, jak poprawnie używać formularza.

Poniższy przykład wykonuje następujące kontrole:

  • Adres e-mail w rzeczywistości się zmienił - bardzo przydatne, jeśli trzeba zweryfikować wiadomość e-mail lub zaktualizować szympansa pocztowego;
  • Zarówno e-mail, jak i e-mail potwierdzający są takie same - formularz zawiera dwa pola na e-mail, więc aktualizacja jest mniej podatna na błędy.

Na koniec zapisuje nową wiadomość e-mail w obiekcie użytkownika (aktualizuje wiadomość e-mail użytkownika). Zauważ, że __init__() wymaga obiektu użytkownika.

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow