Diferencias entre default, null y blank en Django

En este articulo explico las diferencias entre default, null y blank en Django.

Los tipos de campo que emplea Django puedes revisarlos en la explicación de los campos en los modelos en su pagina oficial.

Nul

El campo nulo (Null) cuando posee valor TRUE, permitirá  guardar  valores vacíos como NULL en la base de datos. Su valor por defecto  es False.

Dicho esto, las cadenas vacías siempre se guardarán como cadenas vacías, no como NULL.

Por tanto, lo adecuado es usarlo   para campos que no sean cadenas (fechas, enteros, o booleanos.

Blank

El campo blank cuando es TRUE,  puede dejarse en blanco y por  defecto su valor es False.

Blank se diferencia de Null, porque Blank se emplea en validaciones, mientras Null se emplea en la base de datos.

Si un campo blank es True, la validación en el sitio de Django  permitirá que se añada un campo vacío, sino es asi por el contrario, y  blank=False, el campo será requerido.

Por tanto, considerando lo explicado anteriormente al hablar de Null,  si tenemos datos del tipo booleano, date o entero,  y lo hemos declarado null, es entonces  obligatorio también definirlos como  blank=True .

Ya que esto permitirá si valores vacíos en los formularios

logo django
django

Default

El valor por defecto (default) de un campo, ha de ser llamable  y por tanto si es llamable, se llamará cada vez que un objeto nuevo sea creado.

Resumiendo el concepto del uso de estos seria:

  • Usa «default» para definir el valor que se dará a un campo si tu código no lo define.
  • Usa «blank» para validaciones de formulario. blank=True permite que el campo se deje en blanco.
  • Usa «null» si quieres guardar valores vacíos como NULL en la base de datos.

Espero humildemente, que esto sirva de ayuda a alguien.

«El elefante no necesita decir cuan alto es, le basta con caminar»

NS

Error: Provide a one-off default now

django error

Si en alguna ocasión al trabajar con Django, y correr una migración recibes el error Provide a one-off default now, entonces este post puede serte de ayuda.

Este error, suele suceder cuando añadimos a un modelo ya existente, una nueva llave (ForeingKey), con un valor determinado.

En este post mostraré dos formas de hacerlo.

Siguiendo la documentación, Añadir una ForeignKey (non-nullable) en Django se divide en tres pasos:

Veamos primero la situación inicial:

class Post(models.Model):
    name = models.CharField(max_length=100)

Paso 1.

Primero se añade la nueva llave, donde primero definiremos null, como null=TRUE y luego desde consola correremos makemigrations().

Esto creará una nueva migración que añade el campo que hemos creado.a la tabla, por tanto ahora tenemos una nueva columna con todas sus filas con valor Null.

class Post(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, null=True, on_delete=models.CASCADE))

$ python manage.py makemigrations
Migrations for 'mi_App':
  mi_App/migrations/0002_post_category.py
    - Add field author to post

Paso 2

Ahora correremos nuevamente makemigrations, creando una una nueva migración vacía  (makemigrations --empty).

$ python manage.py makemigrations  --empty -n mi_App assign_category
Migrations for 'mi_App':
 mi_App/migrations/0003_assign_category.py

Ahora  editamos esta migración para que contenga los datos que deseamos, y es en este momento donde de acuerdo a nuestra necesidades colocaremos el valor que debe tener la nueva Foreign key.

from django.db import migrations

def assign_category(apps, schema_editor):
    Category= apps.get_model('category', 'Category')  
    Post = apps.get_model('mi_App', 'Post')               
    
    Post.objects.all().update(category=category)  # and bulk update all posts.


class Migration(migrations.Migration):

    dependencies = [...]

    operations = [
        migrations.RunPython(assign_category, migrations.RunPython.noop),
    ]

Otros posts sobre Django

Paso 3

En el tercer paso modificaremos la nueva ForeignKey en nuestro modelo, eliminando la posibilidad de valor nulo:

null=False 

class Post(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, null=False, on_delete=models.CASCADE))

Y creamos una nueva migración corriendo nuevamente makemigrations.

$ python manage.py makemigrations mi_App -n post_category_non_null

Recibirás este mensaje:

You are trying to change the nullable field 'author' on something. to non-nullable without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)
 3) Quit, and let me add a default in models.py

Seleccionamos la opción 2 y problema resuelto.

Migrations for 'mi_App':
  something/migrations/0004_post_author_non_null.py
    - Alter field category on post

Este es el camino más largo, que sugiere la documentación, pero como siempre hay una posibilidad mas corta:

  1. En la carpeta migraciones eliminamos todas la migraciones existentes,
  2. corremos nuevamente makemigrations, con las modificaciones nuevas.
  3. corremos migrate
  4. creamos nuevamente el superusuario

Con esto quedaría resuelto.

Espero sinceramente, que esto sirva de ayuda a alguien .

……..y para cuando a ti te estén rompiendo el alma, ya el tiempo habrá cicatrizado mis heridas.

A. Torres

Un saludo

TypeError: static() got an unexpected keyword argument ‘document_root’ in Django»

django error

El error typeError: static() got an unexpected keyword argument ‘document_root, puede aparecer, en Django cuando intentamos añadir en nuestro urls.py

+= static(settings.MEDIA_URL, documnet_root=settings.MEDIA_ROOT)

Esta modificación de las urls, la hacemos para decirle a Django, en qué lugar se encuentran nuestros archivos media.

Si nos fijamos en el contenido de nuestro archivo settings.py, debe aparecer la dirección que indica , dónde guardamos nuestros archivos estáticos y en que lugar nuestros archivos tipo media.

Es algo asi

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

Dicho esto, el error ‘TypeError: static() got an unexpected keyword argument ‘document_root‘ puede proceder de diversas fuentes, dos de las que conozco y me resultan más comunes son:

 Importar de modo incorrecto la ruta del método static utilizando:

 from django.templatetags.static import static

cuando deberiamos importar

 from django.conf.urls.static import static   

El primero de ellos nos permite manejar archivos estáticos, como css, javascript o imágenes.

El segundo  es una una función helper que nos devuelve la  url,  donde se encuentra un contenido especifico  y su estructura es:

static.static(prefixview=django.views.static.serve**kwargs)

import *

Si, así es. El segundo error es emplear el uso de import *, que por más que pueda parecer cómodo , me ha traído algún de un dolor de cabeza.

En este articulo pueden ampliar conocimiento sobre sus inconvenientes.

“….El amor siempre empieza soñando y termina en insomnio“

R.Arjona

Modelo para guardar un archivo en Django por fecha

logo django

En este articulo intentaré mostrarte como emplear el modelo para guardar un archivo en Django por fecha, lo cual puede ser muy útil al momento de recuperarlo.

Supongamos que tenemos archivos del tipo fotos y notas

Para lograr tenerlos organizarlos por fecha,  la estructura que debe llevar el modelo, puede ser esta en la que los archivos dentro de la carpeta img o la carpeta nota ordenados en el formato año/mes/dia.

foto = models.ImageField(upload_to = 'img/%Y/%m/%d')
nota = models.FileField(upload_to = 'nota/%Y/%m/%d')

Espero sinceramente, haber ayudado a alguien .

Quien siembre 100 boniatos y diga que sembró 200, tendrá que comerse sus mentiras cuando el boniato se le acabe.

D.

Recuperar una imagen en Django, dinámicamente.

logo django

Veamos como recuperar una imagen en Django, para que Django no la dibuje dinámicamente en función del usuario.

Cuando trabajamos en Django, es común colocar el avatar de nuestro usuario en el panel, si tenemos habilitado nuestro modulo "context_procesor", dentro de templates en nuestro archivo setting.py., podemos seguir las instrucciones siguiente.

Otro Post sobre Django

Como recuperar una imagen en Django dinámicamente.

El código para llamar a nuestra imagen podría ser este:

<img src='{{user.avatar.url }}'
alt="{{user.username }}" 
class="class="img-fluid  user_imag rounded-circle">

Si el modulo no estuviera habilitado debemos incluirlo

TEMPLATES = [
 {
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [],
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': [
        'django.template.context_processors.debug',
        'django.template.context_processors.request',     #modulo
        'django.contrib.auth.context_processors.auth',
        'django.contrib.messages.context_processors.messages',
            ],
         },
      },
]

La magia está, en que el método request(), nos traerá la instancia del user a toda pagina que tengamos, por tanto dispondremos de sus atributos, para el usuario visitante.

Recuperando una imagen en el html

Suponiendo que hemos creado nuestro modelo, nuestro form y nuestras url, podemos recuperar a nuestra imagen con

{% for a in object_list  %} 
<section class="dashboard-header section-padding" style=" border:2px solid blue; margin-bottom:15px;">
  <div class="container-fluid">
    <div class="col-lg-3" >
      <img  src='{{a.profile.photouser.url}}'  alt="{{a.user.username}}" class="img-fluid  user_imag rounded-circle">
    </div> …….
 </section>
 {% endfor %} 
  

…. hay que levantarse cada mañana con una esperanza y dormirse cada noche con una meta….

Espero que sirva de ayuda a alguien