Django migration error : TypeError expected string or bytes-like object

Last updated 4 months, 2 weeks ago | 850 views 75     5

Tags:- Django

Django I Migrate Error: TypeError expected string or bytes-like object

"TypeError: expected string or bytes-like object", says the value we have provided for updating the field for the model is not supported. So to resolve this issue we can directly delete the migration file related to the model if there is no record available in the model. But if we have data in our model we can modify the migration file with a supported type value.

let's check with an example:

Assuming we have a model called Post
 

from django.db import models


class InterviewText(models.Model):
    title = TaggableManager()
    description = RichTextField(blank=True, null=True)

    def __str__(self):
        return self.title

Now run the makemigrations and migrate command

D:\project>python manage.py makemigrations
Migrations for 'article':
  post\migrations\0002_post.py
    - Create model Post

D:\project>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, sessions
Running migrations:
  Applying post.0002_post... OK

now add a created field in the model

from django.db import models


class InterviewText(models.Model):
    title = TaggableManager()
    description = RichTextField(blank=True, null=True)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

this time when makemigrations and migrate command run. it will give two option:

 1) Provide a one-off default now (will be set on all existing rows)
 2) Quit, and let me add a default in models.py
 

D:\project>python manage.py makemigrations
You are trying to add the field 'created' with 'auto_now_add=True' to post without a default; the database needs something to populate existing rows.

 1) Provide a one-off default now (will be set on all existing rows)
 2) Quit, and let me add a default in models.py

Select an option: 1
Please enter the default value now, as valid Python
You can accept the default 'timezone.now' by pressing 'Enter' or you can provide another value.
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
[default: timezone.now] >>> 1
Migrations for 'article':
  post\migrations\0002_post_created.py
    - Add field created to post

Above we have selected the 1st option and provided the wrong value as 1 but it created a migration file. Now if we run the migrate command it will start giving the error like "TypeError: expected string or bytes-like object" because it expecting a datetime value.


Now open the "post\migrations\0002_post_created.py" file. we can see that for the field attribute in the operation section there is a default parameter having value 1 which is a wrong value

# Generated by Django 3.0 on 2021-05-11 12:24

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('post', '0002_post'),
    ]

    operations = [
        migrations.AddField(
            model_name='post',
            name='created',
            field=models.DateTimeField(auto_now_add=True, default=1),
            preserve_default=False,
        ),
    ]

To fix this change the default parameter value to "django.utils.timezone.now".

# Generated by Django 3.0 on 2021-05-11 12:24

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

    dependencies = [
        ('post', '0002_post'),
    ]

    operations = [
        migrations.AddField(
            model_name='post',
            name='created',
            field=models.DateTimeField(auto_now_add=True, default=default=django.utils.timezone.now),
            preserve_default=False,
        ),
    ]

Now everything is ok. Run the migrate command

D:\project>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, sessions
Running migrations:
  Applying post.0002_post_created... OK