Zoeken…


ModelForm Voorbeeld

Maak een ModelForm van een bestaande ModelForm , door ModelForm :

from django import forms

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

Een Django-formulier helemaal opnieuw definiëren (met widgets)

Formulieren kunnen op een vergelijkbare manier als modellen worden gedefinieerd door django.forms.Form .
Verschillende CharField zijn beschikbaar zoals CharField , URLField , IntegerField , etc.

Het definiëren van een eenvoudig contactformulier is hieronder te zien:

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 is de weergave van Django van HTML-tags voor gebruikersinvoer en kan worden gebruikt om aangepaste HTML voor formuliervelden weer te geven (bijvoorbeeld: hier wordt een tekstvak weergegeven voor de inhoudinvoer)

attrs zijn attributen die als zodanig naar de gerenderde html voor het formulier worden gekopieerd.

Bijv .: content.render("name", "Your Name") geeft

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

Het veld op basis van voorwaarde van een modelformulier verwijderen uit views.py

Als we een model hebben als volgt,

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

En een modelformulier dat dit model als volgt gebruikt,

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

Merk op dat ik onder de Meta-klasse in formulier een init- functie heb toegevoegd die we kunnen gebruiken tijdens het initialiseren van het formulier vanuit views.py om een formulierveld (of enkele andere acties) te verwijderen. Ik zal dit later uitleggen.

Dit formulier kan dus worden gebruikt voor gebruikersregistratiedoeleinden en we willen alle velden die zijn gedefinieerd in de Meta-klasse van het formulier. Maar wat als we hetzelfde formulier willen gebruiken wanneer we de gebruiker bewerken, maar als we dat niet doen, willen we het admin-veld van het formulier niet weergeven?

We kunnen eenvoudig een extra argument verzenden wanneer we het formulier initialiseren op basis van enige logica en het admin-veld uit de backend verwijderen.

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)

Zoals u kunt zien, heb ik hier een eenvoudig bewerkingsvoorbeeld getoond met behulp van het formulier dat we eerder hebben gemaakt. Merk op dat ik bij het initialiseren van het formulier een extra variabele admin_check heb doorgegeven die True of False .

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

Als je nu het formulier opmerkt dat we eerder schreven, kun je zien dat we in de init proberen de admin_check parameter te vangen die we hier doorgeven. Als de waarde False is, verwijderen we eenvoudigweg het admin veld uit het formulier en gebruiken we het. En aangezien dit een modelformulier admin veld kon niet null in het model zijn, controleren we eenvoudig of het formulier post admin veld in het formulier post had, zo niet stellen we het in op de False in de view code in de volgende code van de view.

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

Bestandsuploads met Django-formulieren

Allereerst moeten we MEDIA_ROOT en MEDIA_URL aan ons bestand settings.py

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

Ook hier werkt u met ImageField , dus onthoud in dergelijke gevallen dat u Pillow-bibliotheek pip install pillow ( pip install pillow ). Anders heb je een dergelijke fout:

ImportError: No module named PIL

Pillow is een vork van PIL, de Python Imaging Library, die niet langer wordt onderhouden. Kussen is achterwaarts compatibel met PIL.

Django wordt geleverd met twee formuliervelden om bestanden naar de server te uploaden, FileField en ImageField , het volgende is een voorbeeld van het gebruik van deze twee velden in ons formulier

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>

Validatie van velden en vastleggen op model (e-mail van gebruiker wijzigen)

Er zijn al formulieren in Django geïmplementeerd om het gebruikerswachtwoord te wijzigen, een voorbeeld is SetPasswordForm .

Er zijn echter geen formulieren om de e-mail van de gebruiker te wijzigen en ik denk dat het volgende voorbeeld belangrijk is om te begrijpen hoe u een formulier correct gebruikt.

In het volgende voorbeeld worden de volgende controles uitgevoerd:

  • E-mail is namelijk veranderd - erg handig als u de e-mail moet valideren of de e-mailchimp moet bijwerken;
  • Zowel e-mail als bevestigings-e-mail zijn hetzelfde - het formulier heeft twee velden voor e-mail, dus de update is minder foutgevoelig.

En uiteindelijk slaat het de nieuwe e-mail op in het gebruikersobject (werkt de e-mail van de gebruiker bij). Merk op dat de methode __init__() een gebruikersobject vereist.

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow