Django之数据库迁移和创建

migrate遇到的一个错误

之前在项目中遇到这样一个问题

  1. 在数据库删除两张表
  2. 在models中注释掉那两张表对应的类
  3. python manage.py makemigrations
  4. python manage.py migrate
    执行上述步骤之后报错了,因为注释掉类,django orm会去数据库帮我们删表,但是此时表已经不存在了。
    解决方式如下:python manage.py migrate --fake
    加上--fake的意思是告诉ORM不要去数据库删表,同步一下删除状态,表示已删除数据库表

创建表

在说明下面内容之前,给出一个建议:使用 ManyToManyFieldForeignKey 应该加上related_name 参数。
考虑相亲情况,简易模型设计如下:

from django.db import models
class User(models.Model):
    name = models.CharField(max_length=32)

    def __str__(self):
        return self.name

class Love(models.Model):
    boy = models.ForeignKey(User)
    girl = models.ForeignKey(User)
    def __str__(self):
        return str(self.id)

上述模型建表会报错,因为ForeignKey不加related_name 参数反向查找用表名_set,在这里是love_set。
这里假设有一个User对象obj, obj.love_set.all() 本质是做以下事情:拿到obj的id,拿到这个id去Love表去匹配,
因为外键管理的是同一张表,所以ORM不知道这里的这个User对象obj的id对应的是girl还是boy设置的外键,加了related_name 参数如下:

from django.db import models

class User(models.Model):
    name = models.CharField(max_length=32)
    

    def __str__(self):
        return self.name

class Love(models.Model):
    boy = models.ForeignKey(User, related_name='g')
    girl = models.ForeignKey(User, related_name='b')
    def __str__(self):
        return str(self.id)

obj.b.all() 做的事就是表示obj的id对应的是girl的外键,这样做了严格区分。
看下面一种情况就不需要加related_name 参数

from django.db import models
class Boy(models.Model):
    name = models.CharField(max_length=32)
    def __str__(self):
        return self.name

class Girl(models.Model):
    name = models.CharField(max_length=32)
    def __str__(self):
        return self.name

class Love(models.Model):
    boy = models.ForeignKey(Boy)
    girl = models.ForeignKey(Girl)
    def __str__(self):
        return str(self.id)

拿到一个Boy对象obj,obj.love_set.all() 拿到Boy对象obj.id, 这个id对应boy对应的外键,因为boy外键关联的是Boy类,这个就是
和前面外键对应同一张表的不同。
其实,思考这个问题,应该在脑海里绘制几张表,然后连线。
用上述思维思考,得到的结论是在一张表设置外键关联本身或者设置 ManyToManyField都不需要加related_name

from django.db import models

# Create your models here.

class UserInfo(models.Model):
    name = models.CharField(max_length=32)

class News(models.Model):
    title = models.CharField(max_length=32)

class Comment(models.Model):
    content = models.CharField(max_length=32)
    user_info = models.ForeignKey('UserInfo')
    news = models.ForeignKey('News')
    parent = models.ForeignKey("self",related_name='o',null=True)
    ctime = models.DateTimeField(auto_now_add=True,null=True)
from django.db import models

class User(models.Model):
    name = models.CharField(max_length=32)
    love = models.ManyToManyField("User")

    def __str__(self):
        return self.name

尽管如此,为了规范,建议以后还是加上

原文地址:https://www.cnblogs.com/longyunfeigu/p/9148742.html