Home > database >  How to assign a user to a model in my database
How to assign a user to a model in my database

Time:05-21

    from django.db import models
    from datetime import datetime
    from django.contrib.auth import get_user_model

    User = get_user_model()


    class Blog(models.Model): 
        user = models.ForeignKey(User, on_delete=models.CASCADE)
        headline = models.CharField(max_length=250)
        content = models.CharField(max_length=2050)
        time_created = models.DateTimeField(default=datetime.now, blank=True)

        def __str__(self):
            return self.user.username

every time I migrate this

"(venv) PS C:\Users\user\Desktop\APPS\web_app_project> python manage.py makemigrations"

I always get this message:

"It is impossible to add a non-nullable field 'user' to blog without specifying a default. This is because 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. Quit and manually define a default value in models.py.

Select an option:"

How do I go about this

CodePudding user response:

Because you've added the non-nullable field user to Blog Django needs to add a user to all instances of blogs in the database, both new ones and existing. If you've created a blog instance in the database, what should Django do with its new user column? That's what it is asking you.

Only if there is no data in the database or you are completely OK with losing data, you can migrate your app to zero with python manage.py migrate <your app name> zero (You might want to reverse to migration besides zero. You can read more about reverse migrations). This will effectively undo all of your migrations for that app. You can then delete the existing migrations for that app and run makemigrations again. Django will no longer complain about the non-nullable field user, as this results in a migration that creates a Blog table with a user field, instead of a migration that attempts to add a user field to an existing Blog table. Once again, do not do this unless you are OK with losing data. This should never be done if your app is already running in production, but it is OK if you have never deployed the app and have no "real" data, and you are still in the initial development phase. Also, make sure you have a backup of deleted migrations in case you need to add them back.

As others have suggested, you can create a default user model that is used as the one-time default to add users to Blogs. For example (in Django shell)

from django.contrib.auth import get_user_model

User = get_user_model()
user = User(username='default_blog_user')
user.set_unusable_password() # Nobody should be able to log in as this user
user.save()
print(user.id) # keep this ID

Then, in the migration, you can use whatever that user.id value was as the one-time-default. But this once again assumes that you haven't deployed to production, as the one-time-default and the IDs in development and production may not match.

If you have already deployed to production, I think the only thing you can do is make the user field nullable for the sake of your migration, but assert that it is not null in your programming logic. For example, by adding a validator to the field.


Side note: instead of running get_user_model in your models module, you should do this:

from django.conf import settings

class Blog(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    # etc.

When you define a foreign key or many-to-many relations to the user model, you should specify the custom model using the AUTH_USER_MODEL setting.

source

CodePudding user response:

You could probably get away with adding the user manually by using the python shellpython manage.py shell then import the required models.

https://stackoverflow.com/a/5150535/15383032

CodePudding user response:

Maybe add a UUID to your User Model and make the fields that require a user in other models a CharField that stores the Users UUID.

  • Related