Buscar..


Ejemplo de ModelForm

Cree un ModelForm a partir de una clase Model existente, subclasificando ModelForm :

from django import forms

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

Definiendo un formulario Django desde cero (con widgets)

Los formularios se pueden definir, de manera similar a los modelos, subclasificando django.forms.Form .
Varias opciones de entrada de campo están disponibles, como CharField , URLField , IntegerField , etc.

La definición de un formulario de contacto simple se puede ver a continuación:

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 es la representación de Django de las etiquetas de entrada de usuario HTML y se puede usar para representar html personalizados para campos de formulario (por ejemplo, como se representa un cuadro de texto para la entrada de contenido aquí)

attrs atributos son atributos que se copiarán tal como están en el HTML procesado para el formulario.

Por ejemplo: content.render("name", "Your Name") da

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

Eliminando un campo de modelForm basado en la condición de views.py

Si tenemos un modelo como el siguiente,

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

Y una forma modelo que utiliza este modelo como sigue,

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

Tenga en cuenta que debajo de la clase Meta en el formulario agregué una función de inicio que podemos usar mientras inicializamos el formulario desde views.py para eliminar un campo de formulario (o algunas otras acciones). Te lo explicaré más tarde.

Por lo tanto, este formulario se puede utilizar para fines de registro de usuario y queremos que todos los campos estén definidos en la clase Meta del formulario. Pero, ¿qué pasa si queremos usar el mismo formulario cuando editamos al usuario pero cuando lo hacemos no queremos mostrar el campo de administración del formulario?

Simplemente podemos enviar un argumento adicional cuando inicializamos el formulario en base a alguna lógica y eliminamos el campo de administración del 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)

Como puede ver, he mostrado aquí un ejemplo de edición simple utilizando el formulario que creamos anteriormente. Observe que cuando inicialicé el formulario pasé una variable admin_check adicional que contiene True o False .

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

Ahora, si observa el formulario que escribimos anteriormente, puede ver que en el inicio intentamos capturar el admin_check que pasamos desde aquí. Si el valor es Falso, simplemente eliminamos el Campo de admin del formulario y lo usamos. Y dado que este es un modelo, el campo de administrador no puede ser nulo en el modelo, simplemente verificamos si la publicación de formulario tenía un campo de administrador en la publicación de formulario, si no lo configuramos como False en el código de vista en el siguiente código de vista.

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

Cargas de archivos con Django Forms

En primer lugar, debemos agregar MEDIA_ROOT y MEDIA_URL a nuestro archivo settings.py

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

También aquí trabajará con ImageField , así que recuerde que en tales casos instale la biblioteca Pillow ( pip install pillow ). De lo contrario, tendrá tal error:

ImportError: No module named PIL

Pillow es una bifurcación de PIL, la biblioteca de imágenes de Python, que ya no se mantiene. La almohada es compatible con PIL.

Django viene con dos campos de formulario para cargar archivos al servidor, FileField e ImageField , el siguiente es un ejemplo del uso de estos dos campos en nuestro formulario

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>

Validación de campos y Confirmar modelo (Cambiar correo electrónico de usuario)

Ya hay formularios implementados dentro de Django para cambiar la contraseña del usuario, un ejemplo es SetPasswordForm .

Sin embargo, no hay formularios para modificar el correo electrónico del usuario y creo que el siguiente ejemplo es importante para entender cómo usar un formulario correctamente.

El siguiente ejemplo realiza las siguientes comprobaciones:

  • De hecho, el correo electrónico ha cambiado; es muy útil si necesita validar el correo electrónico o actualizar el correo de chimpancé;
  • Tanto el correo electrónico como el correo electrónico de confirmación son los mismos: el formulario tiene dos campos para correo electrónico, por lo que la actualización es menos propensa a errores.

Y al final, guarda el nuevo correo electrónico en el objeto de usuario (actualiza el correo electrónico del usuario). Observe que el __init__() requiere un objeto de usuario.

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow