How to modify a models who's already migrated in Database?

Related searches

I am new to django, I want to modify my models (Which is already in my sqlite3 database) without bugging my entire project. Last time I modified my models it took me hours to fix it cause I bugged the whole project. So I dont want to make the same error, could you guys help me witht the commands please? Thanks for helping

models.py (at the moment)

from django.db import models

THE_GENDER = [
    ("Monsieur", "Monsieur"),
    ("Madame", "Madame")
]


class Post(models.Model):


    name = models.CharField(max_length=100)
    email = models.CharField(max_length=100)
    gender = models.CharField(max_length=8, choices=THE_GENDER)
    number = models.CharField(max_length=100)


    def __str__(self):
        return self.name

The edit that I want to make to the models (I want to add an author user into the models. So i know whos making the form.)

from django.db import models
from django.contrib.auth.models import User

THE_GENDER = [
    ("Monsieur", "Monsieur"),
    ("Madame", "Madame")
]


class Post(models.Model):


    name = models.CharField(max_length=100)
    email = models.CharField(max_length=100)
    gender = models.CharField(max_length=8, choices=THE_GENDER)
    number = models.CharField(max_length=100)
    author = models.ForeignKey(User, on_delete=models.CASCADE)


    def __str__(self):
        return self.name

my admin.py files (not sure If ill need to leave it the same or modify it)

from django.contrib import admin
from .models import Post

admin.site.register(Post)

my forms.py files

from django import forms
from .models import Post
from crispy_forms.helper import FormHelper


class post_form(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(post_form, self).__init__(*args, **kwargs)

        self.helper = FormHelper(self)

    class Meta:
        model = Post
        fields = ["name", "email", "gender", "number"]


views.py

from django.shortcuts import render
from django.http import HttpResponse
from .forms import post_form


# Create your views here.
def home(request):
    form = post_form(request.POST or None)
    if form.is_valid():
        form.save()

    context = {
        "form": form
    }


    return render(request, "sms/home.html", context)

To elaborate on my comment above...

Adding a new non-nullable ForeignKey in Django is generally a three-step process.

  1. First, you add the new ForeignKey to your model definition with null=True, and run makemigrations. This will create a migration that will add the field, nothing special about it. Executing this migration will add a column with all rows having NULL as the value.
  2. Second, you create a new empty migration for the same app (makemigrations --empty), then edit that migration to contain a data migration step. This is where you'll need to, according to your business logic, choose some value for the new foreign key.
  3. Third, you modify the ForeignKey in your model definition to set null=False and create a third migration with makemigrations. Django will ask whether you've dealt with nulls somehow – you need to say that "yep, I swear I have" (since you did, above in step 2).

In practice, for a simplified version of OP's question where we'll want to add an User foreign key:

Original state
class Post(models.Model):
    name = models.CharField(max_length=100)
1a. Add nullable field.
class Post(models.Model):
    name = models.CharField(max_length=100)
    author = models.ForeignKey(User, null=True, on_delete=models.CASCADE))
1b. Run makemigrations.
$ python manage.py makemigrations
Migrations for 'something':
  something/migrations/0002_post_author.py
    - Add field author to post
2a. Create a new empty migration.
$ python manage.py makemigrations something --empty -n assign_author
Migrations for 'something':
  something/migrations/0003_assign_author.py
2b. Edit the migration file.

More information on data migrations can be found, as always, in the manual.

from django.db import migrations


def assign_author(apps, schema_editor):
    User = apps.get_model('auth', 'User')  # or whatever is your User model
    Post = apps.get_model('something', 'Post')  # or wherever your Post model is
    user = User.objects.filter(is_superuser=True).first()  # Choose some user...
    assert user  # ... and ensure it exists...
    Post.objects.all().update(author=user)  # and bulk update all posts.


class Migration(migrations.Migration):

    dependencies = [...]

    operations = [
        migrations.RunPython(assign_author, migrations.RunPython.noop),
    ]
3a. Make the field non-nullable.
class Post(models.Model):
    name = models.CharField(max_length=100)
    author = models.ForeignKey(User, null=False, on_delete=models.CASCADE))
3b. Run Makemigrations.

Answer truthfully to the question – you've just added a RunPython operation.

$ python manage.py makemigrations something -n post_author_non_null
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
Select an option: 2
Migrations for 'something':
  something/migrations/0004_post_author_non_null.py
    - Alter field author on post
All done!

Running migrate will now run these three migrations and your model will have author without data loss.

7 Fundamental Change Management Models, Change management generally refers to how teams and companies implement organizational change. Learn 7 tried-and-true change management models that � McKinsey 7S Model (Click on image to modify online) PDCA model. Also known as the Deming wheel or control cycle, the PDCA model was developed by William Deming during the 1950s. Standing for Plan-Do-Act-Change, the PDCA model is a cyclical and iterative process for continuous change and improvement.

First you need to edit your models.py

# models.py
class Post(models.Model):
    name = models.CharField(max_length=100)
    email = models.CharField(max_length=100)
    gender = models.CharField(max_length=8, choices=THE_GENDER)
    number = models.CharField(max_length=100)
    author = models.ForeignKey(User, on_delete=models.CASCADE) # add new field

    def __str__(self):
        return self.name

Since you added new field author, you have to run makemigrations command and then the migrate command. During migrations, you may be asked to provide a default value for author field for existing Post instances. In that time, you can "interactively" provide values via Django shell. Any valid PK of User instances will be a valid input during the time. FYI: This is a onetime process

After that, change your home(...) view as,

from django.contrib.auth.decorators import login_required


@login_required
def home(request):
    form = post_form(request.POST or None)
    if form.is_valid():
        instance = form.save(commit=False)
        instance.auther = request.user
        instance.save()

    context = {
        "form": form
    }

    return render(request, "sms/home.html", context)

Note: You should use @login_required(...) decorator to get the authenticated user in request.user attribute.

6 Essential Change Management Models to Help Innovate & Grow , 17:22. 0:00 / 17:22. Live. •. Scroll for details. How To Edit Models | Model Editing. 207 views207 Duration: 17:22 Posted: May 31, 2017 Change rarely follows the exact steps change management models suggest. However, it's always good to work to a plan, especially using a model that's based on experience and observation. So, explore these models of change management and take what is valuable to you.

Your migration is tricky, because you want every Post related to a user. To workaround this you can do the following:

Add your new field with null=True models.ForeignKey(User, on_delete=models.CASCADE, null=True) then manage.py makemigrations then you have to decide what to do. Either (1) add authors to your existing posts by hand, or (2) delete them all

manage.py shell
from x.models import Post
from django.contrib.auth.models import User

# 1
user = User.objects.get(id=1) # get your user
Post.objects.all().update(author=user)

# or 2
Post.objects.all().delete()

then you can finally set your authors like you want them: models.ForeignKey(User, on_delete=models.CASCADE) again manage.py makemigrations

See the comments for more information

How To Edit Models, I wonder if I can modify the available models (like TAM, UTAUT) for my research? Can anyone advise me how this modification should be done� Almost all visual models used in movies and video games are shell models. Software Next in our guide is the software that helps you design. 3-D software enables engineers and architects to design, inspect, and manage engineering projects within an integrated graphical user interface (GUI) on a personal computer system.

You can handle this issue in different ways.

If there is no data, you can easily add the new field and run your migrations. You should be fine

If you already have posts, you can allow the field to be nullable, then run your migrations before going to populate it.

A more intuitive way of doing this especially if you already have data is to assign a user to the post while running the migrations.

First create a migration with the author field allowed to be null, then

author = models.ForeignKey(User, null=True, on_delete=models.CASCADE)

manage.py makemigrations manage.py migrate

after that, remove the null attribute.

author = models.ForeignKey(User, on_delete=models.CASCADE)

manage.py makemigrations

open the migration file now generated which will be which you will modify with a custom method like below and run migrate after that.

from django.db import migrations, models


# create custom method
def add_author(apps, schema_editor):
    User = apps.get_model('auth', 'User')  
    Post = apps.get_model('something', 'Post')  
    posts = Post.objects.all()
    author = User.object.get(id=1) # whichever user you want to use as the author
    for post in posts:
        post.author = author
        post.save()

class Migration(migrations.Migration):

    dependencies = [
        ('posts', '00000000'),
    ]

    operations = [
        migrations.RunPython(add_author), # this will run the method above
        migrations.AlterField(
            model_name='post',
            name='author',
            field=models.ForeignKeyField...,
        ),

    ]

check this link for a more detailed explanation of how this works

How to modify models?, Lewin's Change Management Model Process Checklist splits the process of change into three stages, which account for both the processes and� On the Modeling tab, click Model Data Editor or press Ctrl+H. In the Model Explorer Model Hierarchy pane, expand the node for your model, and select the model workspace. Select Add > MATLAB Variable. You can similarly use the Add menu or toolbar to add a Simulink.Parameter object to a model workspace.

8 Critical Change Management Models to Evolve and Survive , i have a model and i need to let user edit data inside it using django forms or any other way. look at the image above , i want to show this form ready populated with the data and let user update it.

How to Modify a Die-Cast Car: This instructable covers how to take an ordinary die-cast car and modify it using basic tools. It will cover how to properly repaint it, add a carbon-fiber hood, add a carbon-fiber splitter, as well as create a carbon-fiber spoiler.

Comments
  • if you haven't created any posts yet, you can go ahead and add the author, also you don't need to change anything in the admin
  • Can you add your views.py as well?
  • @Bernard'BetaBerlin'Parah I made two post. Can I go to the admin page and delete both and than add the author or it will bug the project?
  • @ArakkalAbu Yes, I added the views,py
  • wait, don't do anything yet. I will show you the best way to handle this incase you ever encounter it
  • I love this method too
  • Thansk you a lot for the clear explination. It worked.
  • Thanks for the answer. Ill check it out in a couples of minutes
  • This does not take into account the migration needing a default value for author...
  • If i run this command on the manage.py shell after I made the migrations post_1 = Post(name="oliver", email="oliver@gmail.com", gender="Monsieur", author=user) Would it work fine?
  • @tiberhockey You will be asked to give a default value for existing rows. In that time you can provide any valid PK's of existing User' instance.
  • @AKX I have updated the answer :) I hope it conveys info.
  • No, deleting data is never the right option. Instead, for migrations that need to add a foreign key, the correct method is to add the FK as nullable, then add a data migration (migrations.RunPython/migrations.RunSQL) that figures out a suitable value, then remove null=True off the FK and generate a migration again.