如何修改数据库中已经迁移的模型?

tib*_*key 3 python authentication django django-models

我是 django 的新手,我想修改我的模型(它已经在我的 sqlite3 数据库中)而不妨碍我的整个项目。上次我修改模型时花了几个小时才修复它,因为我对整个项目进行了窃听。所以我不想犯同样的错误,你们能帮我处理命令吗?感谢您的帮助

models.py(目前)

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
Run Code Online (Sandbox Code Playgroud)

我想要对模型进行的编辑(我想将作者用户添加到模型中。所以我知道谁在制作表单。)

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
Run Code Online (Sandbox Code Playgroud)

我的 admin.py 文件(不确定是否需要保持不变或修改它)

from django.contrib import admin
from .models import Post

admin.site.register(Post)
Run Code Online (Sandbox Code Playgroud)

我的 forms.py 文件

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"]


Run Code Online (Sandbox Code Playgroud)

视图.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)
Run Code Online (Sandbox Code Playgroud)

AKX*_*AKX 7

详细说明我上面的评论......

\n\n

在 Django 中添加新的不可为 null 的foreignkey通常是一个三步过程。

\n\n
    \n
  1. 首先,使用 , 将新的外键添加到模型定义中null=True,然后运行makemigrations。这将创建一个将添加该字段的迁移,没有什么特别的。执行此迁移将添加一列,其中所有行都具有NULL该值。
  2. \n
  3. 其次,为同一应用程序创建一个新的空迁移 ( makemigrations --empty),然后编辑该迁移以包含数据迁移步骤。您需要根据您的业务逻辑,为新外键选择一些值。
  4. \n
  5. 第三,修改模型定义中的foreignkey以设置null=False并创建第三个迁移makemigrations。Django 会问你是否以某种方式处理过nulls \xe2\x80\x93 你需要说“是的,我发誓我已经”(因为你已经这样做了,在上面的步骤 2 中)。
  6. \n
\n\n

在实践中,对于OP问题的简化版本,我们需要添加一个用户外键:

\n\n

原始状态

\n\n
class Post(models.Model):\n    name = models.CharField(max_length=100)\n
Run Code Online (Sandbox Code Playgroud)\n\n

1a. 添加可为空的字段。

\n\n
class Post(models.Model):\n    name = models.CharField(max_length=100)\n    author = models.ForeignKey(User, null=True, on_delete=models.CASCADE))\n
Run Code Online (Sandbox Code Playgroud)\n\n

1b. 运行 makemigrations。

\n\n
$ python manage.py makemigrations\nMigrations for \'something\':\n  something/migrations/0002_post_author.py\n    - Add field author to post\n
Run Code Online (Sandbox Code Playgroud)\n\n

2a. 创建一个新的空迁移。

\n\n
$ python manage.py makemigrations something --empty -n assign_author\nMigrations for \'something\':\n  something/migrations/0003_assign_author.py\n
Run Code Online (Sandbox Code Playgroud)\n\n

2b. 编辑迁移文件。

\n\n

与往常一样,可以在手册中找到有关数据迁移的更多信息。

\n\n
class Post(models.Model):\n    name = models.CharField(max_length=100)\n
Run Code Online (Sandbox Code Playgroud)\n\n

3a. 使该字段不可为空。

\n\n
class Post(models.Model):\n    name = models.CharField(max_length=100)\n    author = models.ForeignKey(User, null=True, on_delete=models.CASCADE))\n
Run Code Online (Sandbox Code Playgroud)\n\n

3b. 运行 Makemigrations。

\n\n

如实回答问题 \xe2\x80\x93 您刚刚添加了 RunPython 操作。

\n\n
$ python manage.py makemigrations something -n post_author_non_null\nYou 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).\nPlease select a fix:\n 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)\n 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)\n 3) Quit, and let me add a default in models.py\nSelect an option: 2\nMigrations for \'something\':\n  something/migrations/0004_post_author_non_null.py\n    - Alter field author on post\n
Run Code Online (Sandbox Code Playgroud)\n\n

全做完了!

\n\n

运行migrate现在将运行这三个迁移,并且您的模型将不会author丢失数据。

\n