No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Formularios en Django

24/37
Recursos

La clase utilitaria para formularios de Django nos ayuda a resolver mucho del trabajo que se realiza de forma repetitiva. La forma de implementarla es muy similar a la implementaci贸n de la clase models.model.

Algunas de las clases disponibles en Django al implementar form, son:

  • BooleanField
  • CharField
  • ChoiceField
  • TypedChoiceField
  • DateField
  • DateTimeField
  • DecimalField
  • EmailField
  • FileField
  • ImageField"

Aportes 46

Preguntas 35

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Reg铆strate o inicia sesi贸n para participar.

Dejare aqu铆 el c贸digo update_profile.html del inicio de la clase del minuto 0 por si alguien lo quiere, este c贸digo lo copie viendo la pantalla.

{% extends "base.html" %}
{% load static %}

{% block head_content %}
<title>@{{ request.user.username }} | Update profiles</title>
{% endblock %}

{% block container %}

<div class="container">

    <div class="row justify-content-md-center">
        <div class="col-6 p-4" id="profile-box">

            <form>
                
                <div class='media'>
                    <img src="{% static 'img/default-profile.png' %}" class="rounded-circle" height="50"/>
                    
                    <div class="media-body">
                        <h5 class="ml-4">@{{ user.username }} | {{user.get_full_name}}</h5>
                        <p class="ml-4"><input type="file" name="picture" required="true"></p>
                    </div>
                </div>

                <hr><br>

                <div class="form-group">
                    <label>Website</label>
                    <input class="form-control" type="url" name="website" placeholder="Website"/>
                </div>
            
                <div class="form-group">
                    <label>Biography</label>
                    <textarea class="form-control" name="biography">{{ profile.biography }}</textarea>
                </div>

                <div class="form-group">
                    <label>Phone number</label>
                    <input
                        class="form-control"
                        type="text"
                        name="phone_number"
                        placeholder="Phone number"
                        value="{{ profile.phone_number }}"
                    />
                </div>

                <button type="submit" class="btn btn-primary btn-block mt-5">Update info</button>
            </form>
        </div>
    </div>
</div>
{% endblock %}

Buscando en la documentaci贸n, consegu铆 una forma de incluir un mensaje que nos avise que se actualiz贸 el perfil de manera satisfactoria鈥 Este ser铆a lo que debemos incluir en el c贸digo:

views.py

from django.contrib import messages

...
if form.is_valid():
            data = form.cleaned_data

            profile.website = data['website']
            profile.phone_number = data['phone_number']
            profile.biography = data['biography']
            profile.picture = data['picture']
            profile.save()
            messages.success(request, 'Your profile has been updated!')

            return redirect('update_profile')
...

update_profile.html

{% if messages %}
                    <ul class="messages list-unstyled">
                        {% for message in messages %}
                        <li  {% if message.tags %} class="alert alert-success {{ message.tags }} " {% endif %}> {{ message }} </li>
                        {% endfor %}
                    </ul>
                {% endif %}

No me aguant茅 las ganas de que los errores se vieran tan mal entonces decid铆 hacerlo por mi cuenta. Quiz谩s en el siguiente v铆deo exista una manera m谩s 贸ptima ya que es un errorList de Django.

update_profile.html

<form ...>
  {% for field in form %}
    {% if field.errors %}
      <p class="alert alert-danger">{{ field.label }}: {{ field.errors|striptags }}</p>
    {% endif %}
  {% endfor %}
  ...

update_profile.html

{% extends "base.html" %}
{% load static %}

{% block head_content %}
<title>@{{ request.user.username }}</title>
{% endblock %}

{% block container %}

  <div class="container">

    <div class="row justify-content-md-center">
      <div class="col-6 p-4" id="profile-box">

        <form action="{% url 'update_profile' %}" method="POST" enctype="multipart/form-data">
          {% csrf_token %}

          {% if form.errors %}
            <p class="alert alert-danger">{{ form.error }}</p>
          {% endif %}

          <div class="media">
            {% if profile.picture %}
              <img src="{{ profile.picture.url }}" class="rounded-circle" height="50" />
            {% else %}
              <img src="{% static 'img/default-profile.png' %}" class="rounded-circle" height="50" />
            {% endif %}

            <div class="media-body">
              <h5 class="ml-4">@{{ user.username }} | {{ user.get_full_name }}</h5>
              <p class="ml-4"><input type="file" name="picture" required="true"></p>
            </div>
          </div>

          <hr><br>

          <div class="">
            <label>Website</label>
            <input
                class="form-control"
                name="website"
                type="url"
                placeholder="Website"
                value="{{ profile.website }}"
                />
          </div>

          <div class="">
            <label>Biography</label>
            <textarea class="form-control" name="biography">{{ profile.biography }}</textarea>
          </div>

          <div class="">
            <label>Phone number</label>
            <input
                class="form-control"
                name="phone_number"
                type="text"
                placeholder="Phone number"
                value="{{ profile.phone_number }}"
                />
          </div>

          <button class="btn btn-primary btn-block mt-5" type="submit">Submit</button>
        </form>
      </div>
    </div>
  </div>
{% endblock %}

Si no les funciona {{profile.username}} o {{profile.phone_number}},
intenten con: {{user.profile.username}} o {{user.profile.phone_number}}
a mi me funciono de la segunda forma

Documentation Link Django 3.0: https://docs.djangoproject.com/en/3.0/

Hola, uso VSCode y tengo las extensiones de python, django instaladas. Pero siempre el editor de c贸digo me muestra un error en los imports de Django (ex. from django.urls import reverse). Sin embargo, el c贸digo funciona bien. El servidor y el proyecto funcionan perfectamente.

Esto no afecta a la funcionalidad del proyecto pero me estresa un poco que muestre un error que no existe 馃槃

Alguien sabe que extensi贸n me ayudar铆a o chacer para que VSCode no muestre estos errores???

Pd. es en todos los archivos del documento, no s贸lo el de middleware.py!

Si bien es de django 2 lo estoy usando para django3 hace como 2 a帽os que no usaba django que hermoso que es y lo digo cada vez que descubro cosas nuevas

Si tienen el problema de que no les muestre los errores, yo lo solucion茅 pasandole los par谩metros del request al instanciar form en el else.

c贸digo:

<def update_view(request):
    profile = request.user.profile
    if request.method == 'POST':
        form = ProfileForm(request.POST, request.FILES)
        if form.is_valid():
            data = form.cleaned_data
            profile.website = data['website']
            profile.phone_number = data['phone_number']
            profile.biography = data['biography']
            profile.picture = data['picture']
            profile.save()
            return redirect('update')
        else:
            form = ProfileForm(request.POST, request.FILES)> 

A quien no le est茅 funcionando el formulario y le est茅 botando error al cargar el static, pongan {% load static %} justo debajo del {% block container %} 鈾

Cap24: Formularios en Django.

La clase utilitaria para formularios de Django nos ayuda a resolver mucho del trabajo que se realiza de forma repetitiva. La forma de implementarla es muy similar a la implementaci贸n de la clase models.model.
.
Como dijimos, los formularios en Django se construyen a partir de la clase Form, estos contienen fields que corresponden al tipo de dato esperado para el usuario, Estos, tambi茅n son clases que poseen atributos. Por ejemplo, si hablamos de un CharField, este tendra el atributo max_lenght, que determinara el m谩ximo numero de caracteres para ese campo, entre otros validadores.

Algunas de las clases disponibles en Django al implementar form, son:

  • BooleanField
  • CharField
  • ChoiceField
  • TypedChoiceField
  • DateField
  • DateTimeField
  • DecimalField
  • EmailField
  • FileField
  • ImageField

.
.
La informaci贸n enviada es procesada por una vista o view, la que generalmente es la misma que publica el formulario. Esto nos permite reutilizar cierta parte de la misma logica.
Ex:

Si llegamos a la vista con una petici贸n con el m茅todo GET, creara una instancia vac铆a del formulario y la pondr谩 en el contexto template para ser 鈥榬endereada鈥.
.
Si el formulario es enviado con el metodo POST, la vista creara nuevamente una instancia del formulario y lo vinculara con la informaci贸n del request:
form = NameForm(request.POST). Esto es llamado 鈥榲inculaci贸n de datos al formulario鈥.

Nota: Recordemos que request.POST es un atributo de la clase HttpRequest en forma de diccionario, mas precisamente un objeto QueryDict, que contiene todos los par谩metro HTTP POST enviados siempre que la solicitud contenga datos del formulario.

.
.
Una instancia de la clase Form tiene el metodo is_valid(), que corre validaciones para todos los fields del form. Cuanto este m茅todo es llamado, si la informaci贸n en los campos es valida:

  • Retornara True.
  • La informaci贸n del formulario pasara al atributo cleaned_data.

.
Llamamos al m茅todo is_valid() del formulario; si eso retorna falso, volveremos devuelta al template con el formulario. Esta vez el formulario ya no estar谩 vaci贸, es decir, ahora el formulario que mostraremos en el HTML estar谩 vinculado con la informaci贸n previamente enviada, donde esta podr谩 ser editada o corregida como sea necesario.
.
Si is_valid() es verdadero, ahora estaremos preparados para buscar toda la informaci贸n ya validada del formulario en su atributo cleaned_data. Podemos usar esta informaci贸n para actualizar la base de datos o hacer otros procesos antes de enviar la redirecci贸n HTTP al navegador.
.
.

Form.errors es un atributo al cual se pude acceder aun sin antes haber llamado a is_valid(). Este atributo contiene un diccionario donde las llaves son el nombre del campo o del field antes validado, y los valores son una lista de strings representando el mensaje de error. El error es almacenado en una lista debido a que un campo puede tener m煤ltiples mensajes de errores.
.
Para incluir una imagen en un formulario hay ciertas cosas a tener en cuenta; su field en Django es llamado ImageField. Si se quiere usar este campo, Pillow necesita ser instalado para brindar soporte para el formato de imagen usado. Si se encuentra un error de imagen corrupta cuanso se sube una imagen, usualmente quiere decir que Pillow no entiende ese formato. Para solucionar el problema, se debe instalar correctamente la libraria correspondiende y resintalar Pillow.
.
Ahora, trabajar con archivos e im谩genes en formularios puede ser un poco mas complicado que con un formulario com煤n.
.
Primero que nada, para subir archivos, debes asegurarte de que en tu formulario, esta definido el enctype como multipart/form-data.
.

Nota: enctype describe como viajara la informacion que se mande a traves de un formulario HTML. La forma puede ser de principalmente dos tipos:
鈥 application/x-www-form-urlencoded: Usado por defecto.
鈥 multipart/form-data: Usado cuando el formulario incluya algun input de tipo file.

.
Segundo; cuando usas un formulario, necesitas vincular los datos del archivo. Los datos del archivo son manejados separados de los datos nomales, entonces, si tu formulario contiene un FileField o un ImageField, necesitaras especificar un segundo argumento cuando vincules los datos enviados a tu formulario. En la practica, especificaras a el atributo request.FILES como la fuente de los datos del archivo(Exactamente como lo hac铆amos usando a request.POST como fuente de los datos del formulario.)
Ahora:
form = NameForm(request.POST, request.FILES)
.

Nota: request.FILES es un objeto en forma de diccionario que contiene todas imagenes subidas. Cada llave es el nombre del valor name dentro del input del formulario. Cada valor es una instancia de UploadedFile que maneja todo lo relacionado con la imagen.

.
Cuando el campo ya fue limpiado y validado, el objeto UploadedFile tendra un atributo adicional llamado image que contendra una instancia de Pillow.Image usada para corroborar si la imagen era valida.

Mi c贸digo no carga la foto al momento de ser actualizada, alguien tendr铆a idea de por qu茅 pasa esto? Este es mi c贸digo:

update_profile() en views.py

def update_profile(request):
    """Update a user's profile view."""

    profile = request.user.profile

    if request.method == 'POST':
        form = ProfileForm(request.POST, request.FILES)

        if form.is_valid():
            data = form.cleaned_data

            profile.website = data['website']
            profile.phone_number = data['phone_number']
            profile.biography = data['biography']
            profile.picture = data['picture']

            profile.save()

            messages.success(request, 'Your profile has been updated succesfully!')
            return redirect('update_profile')
    
    else:
        form = ProfileForm()

    return render(
        request=request, 
        template_name='users/update_profile.html',
        context={
            'profile': profile,
            'user': request.user,
            'form': form,
        })

update_profile.html

{% extends "base.html" %}
{% load static %}

{% block head_content %}
<title>@{{ request.user.username }} | Update profile</title>
{% endblock %}

{% block container %}

  <div class="container">

    <div class="row justify-content-md-center">
      <div class="col-6 p-4" id="profile-box">

        <form action="{% url 'update_profile' %}" method="POST" enctype="multipart/form-data">
          {% csrf_token %}

          {% for field in form %}
              {% if field.errors %}
                  <p class="alert alert-danger">{{ field.label }}: {{field.errors|striptags }}</p>
              {% endif %}
          {% endfor %}

          <div class="media">
            {% if profile.picture %}
                <img src="{{ profile.picture.url }}" class="rounded-circle" height="50" />
            {% else %}
                <img src="{% static 'img/default-profile.png' %}" class="rounded-circle" height="50" />
            {% endif %}

            <div class="media-body">
              <h5 class="ml-4">@{{ user.username }} | {{ user.get_full_name }}</h5>
              <p class="ml-4"><input type="file" name="picture" required="true"></p>
            </div>
          </div>

          <hr><br>

          <div class="form-group">
            <label>Website</label>
            <input
                class="form-control"
                type="url"
                name="website"
                placeholder="Website"
                value="{{ profile.website }}"
            />
          </div>

          <div class="form-group">
            <label>Biography</label>
            <textarea class="form-control" name="biography">{{ profile.biography }}</textarea>
          </div>

          <div class="form-group">
            <label>Phone number</label>
            <input
                class="form-control"
                type="text"
                name="phone_number"
                placeholder="Phone number"
                value="{{ profile.phone_number }}"
            />
          </div>

          <button type="submit" class="btn btn-primary btn-block mt-5">Update info</button>
        </form>
      </div>
    </div>
  </div>

{% endblock %}

S铆 a alguien le paso, yo quise imprimir los datos del form al recibir la informaci贸n y la imagen del formulario de manera clara utilizando [form.cleaned_data] pero este m茅todo solo se puede utilizar despu茅s de validar la informaci贸n.
explicaci贸n: https://stackoverflow.com/questions/4308527/django-model-form-object-has-no-attribute-cleaned-data

Cuando corro http://localhost:8000/users/me/profile me aparece el siguiente error, y no puedo descubrir donde esta y como solucionarlo:

AttributeError at /users/me/profile/

鈥楢nonymousUser鈥 object has no attribute 鈥榩rofile鈥

Request Method: GET
Request URL: http://localhost:8000/users/me/profile/
Django Version: 2.1.7
Exception Type: AttributeError
Exception Value:

鈥楢nonymousUser鈥 object has no attribute 鈥榩rofile鈥

Exception Location: C:.env\lib\site-packages\django\utils\functional.py in inner, line 214

Les comparto una peque帽a vista de como me quedo mi formulario de actualizacion de perfil鈥!

Los archivos enviados desde el formulario se capturan en la vista desde request.FILES

Errores comunes en formularios, y lo que debemos enviar

Rol de django en los formularios: Simplificar tareas repetitivas

Luego de agregar el Middleware me arroja este error

RelatedObjectDoesNotExist at /users/me/profile/

C:\Users\jorge\OneDrive\Documents\Platzi\Curso_Django\platzigram\platzigram\middleware.py, line 22, in __call__

                profile = request.user.profile

     

Algui茅n me puede ayudar, no logro arreglarlo.

hola tengo un error en un proyecto en el que trabajo es el siguente django.utils.datastructures.MultiValueDictKeyError alguen me podria decir porque me aparece este erro

Recuerda tambi茅n pasarle al formulario, el valor FILES de request: request.FILES

Si queremos que nuestros forms, puedan recibir diferentes tipos de datos, entonces tenemos que poner en el form, el atributo, enctype ="mutlipart/form-data"

Para hacer formularios de manera limpia, tenemos con Django, la forma de hacer clases, para armar la l贸gica y validaci贸n de los formularios.

Desde el admin, podemos administrar todas la bases de datos.

Para aquellos que no les funcione en el template de update profile el 鈥減rofile.website鈥 (o cualquier llamado usando profile) pueden hacer:

  1. Cambiar 鈥減rofile.website鈥 por 鈥渦ser.profile.website鈥

  2. Hacer el cambio que el profesor hizo (debi贸 mostrar o indicar dicho cambio, creo que nunca lo menciona) y en la funcion update_profile en los modelos de users hacer:

profile = request.user.profile

Espero les ayude

excelente muy bien

Les comparto la funcion de update_profile

def update_profile(request):
    """Update a user's profile view."""
    profile = request.user.profile

    if request.method == 'POST':
        form = ProfileForm(request.POST, request.FILES)
        if form.is_valid():
            data = form.cleaned_data

            profile.website = data['website']
            profile.phone_number = data['phone_number']
            profile.biography = data['biography']
            profile.picture = data['picture']
            profile.save()

            return redirect('update_profile')

    else:
        form = ProfileForm()

    return render(
        request=request,
        template_name='users/update_profile.html',
        context={
            'profile': profile,
            'user': request.user,
            'form': form
        }
    )

Les comparto update_profile

{% extends "base.html" %}
{% load static %}

{% block head_content %}
<title>@{{ request.user.username }} | Update profile</title>
{% endblock %}

{% block container %}

<div class="container">

    <div class="row justify-content-md-center">
        <div class="col-6 p-4" id="profile-box">

            <form action="{% url 'update_profile' %}" method="POST" enctype="multipart/form-data">
                {% csrf_token %}

                {% if form.errors %}
                    <p class="alert alert-danger">{{ form.errors }}</p>
                {% endif %}

                <div class="media">
                    {% if profile.picture %}
                        <img src="{{ profile.picture.url }}" class="rounded-circle" height="50" />
                    {% else%}
                        <img src="{% static 'img/default-profile.png' %}" class="rounded-circle" height="50" />
                    {% endif %}

                    <div class="media-body">
                        <h5 class="ml-4">@{{ user.username }} | {{ user.get_full_name }}</h5>
                        <p class="ml-4"><input type="file" name="picture" required="true"></p>
                    </div>
                </div>

                <hr><br>

                <div class="form-group">
                    <label>Website</label>
                    <input
                        class="form-control"
                        type="url"
                        name="website"
                        placeholder="Website"
                        value="{{ profile.website }}"
                    />
                </div>

                <div class="form-group">
                    <label>Biography</label>
                    <textarea class="form-control" name="biography">{{ profile.biography }}</textarea>
                </div>

                <div class="form-group">
                    <label>Phone number</label>
                    <input
                        class="form-control"
                        type="text"
                        name="phone_number"
                        placeholder="Phone number"
                        value="{{ profile.phone_number }}"
                    />
                </div>

                <button type="submit" class="btn btn-primary btn-block mt-5">Update info</button>
            </form>
        </div>
    </div>
</div>

{% endblock %}

No se muestra la imagen la URL de la imagen que es de MEDIA_URL redirecciona por el middleware as铆 que no se ve, haya alguna forma de excluir al MEDIA_URL as铆 como el logout?

Aun no he entendido la redundancia del modelo Posts y su relacion foranea con User y Perfil a la misma vez

No entiendo qu茅 hace {% csrf_token %}

perfecto, muchas gracias pablo

Que pasa si requiero hacer la validaci贸n de un formulario cuando, en el formulario se encuentran datos a validar de dos o m谩s modelos? 驴Se puede? 驴O solo esta condicionado a que sea de un solo modelo?
Saludos y gracias.

Estoy un poco estancado, no encuentro este error a qu茅 se debe:

La l铆nea 38 que menciona es la de profile.picture = data[鈥榩icture鈥橾

def update_profile(request):

    profile = request.user.profile 

    if request.method == 'POST':
        form = ProfileForm(request.POST, request.FILES)
        if form.is_valid():
            data = form.cleaned_data

            profile.website = data['website']
            profile.phone_number = data['phone_number']
            profile.biography = data['biography']
            profile.picture = data['picture']
            profile.save()

            return redirect('update_profile') #el navegador siempre debe redireccionar a alg煤n lado
    else:
        form = ProfileForm()

Dios si da problemas el c贸digo que hacen aqu铆

驴C贸mo se pasa un** argumento en la URL**? 驴Qu茅 error hay en lo siguiente?
En WEB:
<a class=鈥渘av-link鈥 href="{% url 鈥榯est鈥 ciencia %}">
URLS
path(鈥榯est/modalidad鈥, pregunta_views.pregunta, name=鈥渢est鈥)
VIEWS:
def pregunta(request, modalidad):
reguntas = Pregunta.objects.filter(modalidadPregunta=modalidad)
return render(request, 鈥減regunta/pregunta.html鈥,{鈥榩reguntas鈥:preguntas})

Un saludo.

Siempre debemos hacer un redirect cuando recibamos el formulario, de lo contrario cuando se recargue la pagina har谩 el submit del formulario de nuevo.

Hola, soy el unico al que no le aparece el fullname? alguien sabe como arreglarlo?

se podra? <img src="{{ profile.picture ? 鈥榩rofile.picture.url鈥 : 鈥榠mg/default-profile.png鈥 }}"/>

Comenc茅 haciendo mi propio proyecto con los pasos del profesor, pero con base de datos noSql (MongoDB) tengo un problema cuando respecto lo a este linea, user = models.OneToOneField(User, related_name=鈥減rofile鈥)
pues desde un comienzo sabia que el profesor estaba utilizando base de datos relacionadas, igualmente no la puse en mi c贸digo, ahora tengo el problema de que, como el profesor llama los campos desde la tabla que ya hab铆a creado el, con el identificador user, lo mismo lo puedo hacer en noSql.

Una de las soluciones que se me han ocurrido es crear 2 documentos, en vez de crear un documento embebido.
Si alguien esta manejando mongoDB seria de ayuda que me respondieran este mensaje. Gracias por su atenci贸n.

Formularios en django 2.0.7:

Corrigiendo error para im谩genes

La clase utilitaria para formularios de Django nos ayuda a resolver mucho del trabajo que se realiza de forma repetitiva. La forma de implementarla es muy similar a la implementaci贸n de la clase models.model.

Algunas de las clases disponibles en Django al implementar form, son:

BooleanField
CharField
ChoiceField
TypedChoiceField
DateField
DateTimeField
DecimalField
EmailField
FileField
ImageField"

Excelente, el ejercicio es bastante bueno

驴Por qu茅 en el archivo update_profile.html al obtener los datos del usuario en profile.website , profile.phone_number , etc. no se coloca el request: request.profile.website etc?

Buena clase