Suche…


ModelForm-Beispiel

Erstellen Sie eine ModelForm aus einer vorhandenen Model-Klasse, indem Sie ModelForm subclassing:

from django import forms

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

Django-Formular von Grund auf neu definieren (mit Widgets)

Formulare können auf ähnliche Weise wie Modelle definiert werden, indem django.forms.Form subclassiert django.forms.Form .
Es stehen CharField URLField wie CharField , URLField , IntegerField usw. zur Verfügung.

Das Definieren eines einfachen Kontaktformulars ist unten zu sehen:

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 ist die Darstellung von HTML-Benutzereingabe-Tags in Django und kann verwendet werden, um benutzerdefinierte HTML-Formulare für Formularfelder darzustellen.

attrs sind Attribute, die in das gerenderte HTML für das Formular übernommen werden.

ZB: content.render("name", "Your Name") gibt an

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

Das Entfernen eines Feldes von modelForm basierend auf den Bedingungen aus views.py

Wenn wir ein Modell wie folgt haben,

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

Und eine Modellform, die dieses Modell wie folgt verwendet,

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

Beachten Sie, dass ich unterhalb der Meta-Klasse im Formular eine Init- Funktion hinzugefügt habe, die wir beim Initialisieren des Formulars aus views.py verwenden können, um ein Formularfeld (oder einige andere Aktionen) zu löschen. Ich werde das später erklären.

Dieses Formular kann also für Benutzerregistrierungszwecke verwendet werden und wir möchten, dass alle Felder in der Metaklasse des Formulars definiert werden. Aber was ist, wenn wir dasselbe Formular verwenden möchten, wenn wir den Benutzer bearbeiten, aber wenn wir das Admin-Feld des Formulars nicht anzeigen möchten?

Wir können einfach ein zusätzliches Argument senden, wenn wir das Formular basierend auf einer Logik initialisieren und das Admin-Feld aus dem Backend löschen.

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)

Wie Sie sehen, habe ich hier ein einfaches Bearbeitungsbeispiel mit dem zuvor erstellten Formular gezeigt. Wenn ich das Formular initialisiert habe, habe ich eine zusätzliche admin_check Variable übergeben, die entweder True oder False .

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

Wenn Sie das Formular bemerken, das wir zuvor geschrieben haben, können Sie sehen, dass wir in der init versuchen, den admin_check admin_check abzufangen, den wir hier übergeben. Wenn der Wert False ist, löschen wir einfach das admin Feld aus dem Formular und verwenden es. Und da dies ein Modell-Formularadministratorfeld ist, das im Modell nicht null sein kann, prüfen wir einfach, ob das Formularposting ein Adminfeld im Formularposting hatte. Andernfalls setzen wir es im folgenden Code der Ansicht auf False .

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

Datei-Uploads mit Django-Formularen

Zunächst müssen wir MEDIA_ROOT und MEDIA_URL unserer Datei settings.py hinzufügen

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

Auch hier werden Sie mit ImageField arbeiten. ImageField in solchen Fällen daran, die Pillow-Bibliothek ( pip install pillow ) zu pip install pillow . Andernfalls haben Sie einen solchen Fehler:

ImportError: No module named PIL

Kissen ist eine Abzweigung von PIL, der Python Imaging Library, die nicht mehr gepflegt wird. Kissen ist rückwärtskompatibel mit PIL.

Django enthält zwei Formularfelder, um Dateien auf den Server hochzuladen, FileField und ImageField . Im Folgenden finden Sie ein Beispiel für die Verwendung dieser beiden Felder in unserem Formular

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>

Validierung von Feldern und Commit to model (Benutzer-E-Mail ändern)

In Django sind bereits Formulare implementiert, um das Benutzerpasswort zu ändern. Ein Beispiel ist SetPasswordForm .

Es gibt jedoch keine Formulare zum Ändern der Benutzer-E-Mail, und ich denke, das folgende Beispiel ist wichtig, um zu verstehen, wie man ein Formular korrekt verwendet.

Das folgende Beispiel führt die folgenden Prüfungen durch:

  • E-Mails haben sich tatsächlich geändert - sehr nützlich, wenn Sie die E-Mail-Adresse überprüfen oder den Mail-Schimpansen aktualisieren müssen.
  • Sowohl E-Mail als auch Bestätigungs-E-Mail sind identisch. Das Formular enthält zwei Felder für E-Mail, sodass die Aktualisierung weniger fehleranfällig ist.

Am Ende speichert es die neue E-Mail im Benutzerobjekt (aktualisiert die E-Mail des Benutzers). Beachten Sie, dass für die Methode __init__() ein Benutzerobjekt erforderlich ist.

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow