【问题标题】:Django default information for model模型的Django默认信息
【发布时间】:2020-03-24 20:20:58
【问题描述】:

我有 2 个模型(一个包含我必须上传的默认信息的时间轴,一个包含文件和与时间轴单元之一的关系的 Pdf 模型)。有人告诉我创建自己的迁移文件并执行了以下操作,但出现此错误,并且在网上找不到任何相关信息:

 File "/Users/fetz/Desktop/parentsuportal/parentsuportal/timeline/migrations/0005_auto_20200324_1721.py", line 33, in addData
    Timeline(header = "Transport Support", age = "18-25")
  File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 520, in __hash__
    raise TypeError("Model instances without primary key value are unhashable")
TypeError: Model instances without primary key value are unhashable

我的模型:

HEADER_CHOICES = [
    ('Financial Support', 'Financial Support'),
    ('Educational Support', 'Educational Support'),
    ('Governmental Support', 'Governmental Support '),
    ('Charity Support Groups', 'Charity Support Groups'),
    ('Therapy Support', 'Therapy Support '),
    ('Transport Support', 'Transport Support ')
]
AGE_CHOICES = [
    ('0-4', '0-4'),
    ('4-11', '4-11'),
    ('11-18', '11-18'),
    ('18-25', '18-25')
]

class Timeline(models.Model):
    header = models.CharField(max_length=30, choices=HEADER_CHOICES)
    age = models.CharField(max_length=6, choices=AGE_CHOICES)

class Pdf(models.Model):
    pdf = models.FileField(upload_to='timelinepdfs')
    timeline = models.ForeignKey(Timeline, on_delete=models.CASCADE)

我的迁移文件:

from django.db import migrations

def addData(apps, schema_editor):
    # We can't import the Person model directly as it may be a newer
    # version than this migration expects. We use the historical version.
    Timeline = apps.get_model("timeline", "Timeline")
    timeline = {
        Timeline(header = "Financial Support", age = "0-4"),
        Timeline(header = "Financial Support", age = "4-11"),
        Timeline(header = "Financial Support", age = "11-18"),
        Timeline(header = "Financial Support", age = "18-25"),
        Timeline(header = "Educational Support", age = "0-4"),
        Timeline(header = "Educational Support", age = "4-11"),
        Timeline(header = "Educational Support", age = "11-18"),
        Timeline(header = "Educational Support", age = "18-25"),
        Timeline(header = "Governmental Support", age = "0-4"),
        Timeline(header = "Governmental Support", age = "4-11"),
        Timeline(header = "Governmental Support", age = "11-18"),
        Timeline(header = "Governmental Support", age = "18-25"),
        Timeline(header = "Charity Support Groups", age = "0-4"),
        Timeline(header = "Charity Support Groups", age = "4-11"),
        Timeline(header = "Charity Support Groups", age = "11-18"),
        Timeline(header = "Charity Support Groups", age = "18-25"),
        Timeline(header = "Therapy Support", age = "0-4"),
        Timeline(header = "Therapy Support", age = "4-11"),
        Timeline(header = "Therapy Support", age = "11-18"),
        Timeline(header = "Therapy Support", age = "18-25"),
        Timeline(header = "Transport Support", age = "0-4"),
        Timeline(header = "Transport Support", age = "4-11"),
        Timeline(header = "Transport Support", age = "11-18"),
        Timeline(header = "Transport Support", age = "18-25")
    }
    timeline.save()

class Migration(migrations.Migration):

    dependencies = [
        ('timeline', '0004_auto_20200323_1947'),
    ]

    operations = [
         migrations.RunPython(addData),
    ]

【问题讨论】:

  • “TypeError:没有主键值的模型实例是不可散列的”有很多 SO google 结果
  • @HashRocketSyntax 我尝试使用谷歌搜索,但没有找到任何帮助。这就是我在这里发布我的问题的原因。

标签: django django-models django-migrations


【解决方案1】:

您需要先保存 Timeline 实例,然后才能在集合中使用它。这是因为一个集合使用__hash__ 方法来标识实例(以便集合具有唯一项),而Django 模型类的__hash__ 方法需要一个pk。解决方案是使用不同的集合类,例如列表并对其进行迭代。

timelines = [
    Timeline(header = "Financial Support", age = "0-4"),
    Timeline(header = "Financial Support", age = "4-11"),
    ...
]
for timeline in timelines:
    timeline.save()

或者你可以使用:

Timeline.objects.create(header = "Financial Support", age = "0-4")
Timeline.objects.create(header = "Financial Support", age = "4-11")
...

或者如果您担心它们已经存在:

Timeline.objects.get_or_create(header = "Financial Support", age = "0-4")
Timeline.objects.get_or_create(header = "Financial Support", age = "4-11")
...

【讨论】:

  • 是的,感谢 for 循环工作。感谢您的帮助
猜你喜欢
  • 2018-10-22
  • 2011-09-03
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 2013-02-02
  • 2021-04-03
相关资源
最近更新 更多