【问题标题】:How to pass ForeignKey in dict to create Model object. Django如何在 dict 中传递 ForeignKey 以创建 Model 对象。姜戈
【发布时间】:2020-10-31 13:20:33
【问题描述】:

我创建了一个模型来存储用户名和地点

class UserDetails(models.Model):
    name = models.CharField(max_length=50)
    place = models.ForeignKey(City, on_delete=models.CASECADE)

我有一个 JSON 文件,我有超过 1000 个用户的数据。喜欢

[
    {"name": "A", "place":1},
    {"name": "B", "place":3},
    {"name": "C", "place":4},
    {"name": "D", "place":1},
    ..
    ..
]

place 字段与 City 对象 id 相关。当我使用以下语法时

UserDetails.objects.create(**{"name":"A", "place": 3})

然后得到一个错误,我知道我必须传递 obj 而不是传递地点 id:

loc = City.object.get(id=3)
UserDetails.objects.create(**{"name":"A", "place": loc})

这很好,但是我有大量数据如何传递地点 id 或应该使用 bulk_create 将所有 JSON 数据保存在模型中?

【问题讨论】:

  • 为什么使用UserDetails.objects.create() 而不是简单地使用UserDetails()
  • @EdwinCruz:UserDetails(...) 构造函数不会将对象保存到数据库中。
  • @WillemVanOnsem 我知道,您只需拨打 save() 就可以了。我总是发现自己使用UserDetails( . . . ) 而不是UserDetails.objects.create( . . . )。认为有一个很好的理由,而不仅仅是偏好。

标签: python-3.x django django-models django-rest-framework django-views


【解决方案1】:

这似乎有效:

def model_to_dict_wfk(modelobj):
    opts = modelobj._meta.fields
    modeldict = model_to_dict(modelobj)
    for m in opts:
        if m.is_relation:
            foreignkey = getattr(modelobj, m.name)
            if foreignkey:
                try:
                    modeldict[m.name] = foreignkey
                except:
                    pass
    return modeldict

然后在创建类方法中使用返回的字典

@classmethod
def create(cls, vals):
    obj = cls(**vals)
    obj.save()
    return obj

【讨论】:

  • 如果你能解释一下代码中发生的事情会有所帮助。
  • 它返回一个带有外键作为对象而不是 id 的字典,这允许通过将字典作为 **vals 传递来保存它
  • 我的意思是你可以在你的帖子中解释它:)
【解决方案2】:

您可以改用place_id,这是 Django 创建的存储在数据库中的“双字段”,并存储对目标模型的引用(通常是主键),当然是 Place已经存在:

user_details = [
    UserDetails(name=record['name'], place_id=record['place'])
    for record in list_of_records
]
UserDetails.object.bulk_create(user_details)

list_of_records 因此是您的字典列表。我们可以利用.bulk_create(…) [Django-doc]在少量插入查询中添加所有UserDetails

【讨论】:

  • 嗨@willem,您的解决方案正在运行,谢谢......,现在如果我将字段“place”更改为“place_id”,当我通过列表时是否有任何用于批量创建的语法user_info 字典数据?正如我在用户数据列表示例中提到的......我问这个因为你有什么建议。 "user_details = [ UserDetails(name=record['name'], place_id=record['place']) for record in list_of_records ]".... 将需要时间通过“for 循环”处理所有数据。有没有像 ...create(**data) 这样的方法可以传递该列表。
  • @ShivShankarKeshari:这花费的时间可以忽略不计,特别是因为创建查询(.bulk_create 部分)也可以使用 for 循环。毕竟这里的循环不是瓶颈。通常这是到数据库的往返次数。
猜你喜欢
  • 2016-09-18
  • 2018-02-11
  • 2017-06-15
  • 2021-03-13
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 2012-03-09
相关资源
最近更新 更多