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

Translate »