Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 在seed_data.yaml文件中是否有方法自动生成第一个模型所依赖的模型?_Django_Python 3.x_Yaml_Primary Key_Seeding - Fatal编程技术网

Django 在seed_data.yaml文件中是否有方法自动生成第一个模型所依赖的模型?

Django 在seed_data.yaml文件中是否有方法自动生成第一个模型所依赖的模型?,django,python-3.x,yaml,primary-key,seeding,Django,Python 3.x,Yaml,Primary Key,Seeding,我正在使用Django 2.0、Python 3.7和MySql 5。我有以下两个模型,第二个依赖于第一个 class CoopType(models.Model): name = models.CharField(max_length=200, null=False) class Meta: unique_together = ("name",) class Coop(models.Model): name = models.CharField(m

我正在使用Django 2.0、Python 3.7和MySql 5。我有以下两个模型,第二个依赖于第一个

class CoopType(models.Model):
    name = models.CharField(max_length=200, null=False)

    class Meta:
        unique_together = ("name",)


class Coop(models.Model):
    name = models.CharField(max_length=250, null=False)
    type = models.ForeignKey(CoopType, on_delete=None)
    address = AddressField(on_delete=models.CASCADE)
    enabled = models.BooleanField(default=True, null=False)
    phone = PhoneNumberField(null=True)
    email = models.EmailField(null=True)
    web_site = models.TextField()
我正在为第二个模型创建一些种子数据。我想知道是否有一种方法可以从第二个模型中自动生成第一个模型的数据。我试过这个

- model: maps.coop
  pk: 1
  fields:
    name: "1871"
    type:
      pk: null
      name: Coworking Space
    address:
      street_number: 222
      route: 1212
      raw: 222 W. Merchandise Mart Plaza, Suite 1212
      formatted: 222 W. Merchandise Mart Plaza, Suite 1212
      locality:
        name: Chicago
        postal_code: 60654
        state:
          code: IL
    enabled: True
    phone:
    email:
    web_site: "http://www.1871.com/"
    latitude: 41.88802611
    longitude: -87.63612199
但是我在运行种子数据时遇到了这个错误

(env) localhost:maps davea$ python scripts/parse_coop_csv.py ~/Downloads/chicommons_prep.xlsx\ -\ Mapping\ Sheet.csv > maps/fixtures/seed_data.yaml
(env) localhost:maps davea$ python manage.py loaddata maps/fixtures/seed_data.yaml
Traceback (most recent call last):
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 923, in to_python
    return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'dict'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/serializers/python.py", line 157, in Deserializer
    data[field.attname] = model._meta.get_field(field_name).to_python(field_value)
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 928, in to_python
    params={'value': value},
django.core.exceptions.ValidationError: ["'{'pk': None, 'name': 'Coworking Space'}' value must be an integer."]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/management/__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/management/base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/management/commands/loaddata.py", line 72, in handle
    self.loaddata(fixture_labels)
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/management/commands/loaddata.py", line 113, in loaddata
    self.load_label(fixture_label)
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/management/commands/loaddata.py", line 168, in load_label
    for obj in objects:
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/serializers/pyyaml.py", line 73, in Deserializer
    yield from PythonDeserializer(yaml.load(stream, Loader=SafeLoader), **options)
  File "/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/serializers/python.py", line 159, in Deserializer
    raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value)
django.core.serializers.base.DeserializationError: Problem installing fixture '/Users/davea/Documents/workspace/chicommons/maps/maps/maps/fixtures/seed_data.yaml': ["'{'pk': None, 'name': 'Coworking Space'}' value must be an integer."]: (maps.coop:pk=1) field_value was '{'pk': None, 'name': 'Coworking Space'}'
(env)localhost:maps davea$python scripts/parse_coop_csv.py~/Downloads/chicommons_prep.xlsx\-\Mapping\Sheet.csv>maps/fixtures/seed_data.yaml
(env)localhost:maps davea$python manage.py loaddata maps/fixtures/seed_data.yaml
回溯(最近一次呼叫最后一次):
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/db/models/fields/__init___.py”,第923行,在python中
返回int(值)
TypeError:int()参数必须是字符串、类似于对象的字节或数字,而不是“dict”
在处理上述异常期间,发生了另一个异常:
回溯(最近一次呼叫最后一次):
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/core/serializers/python.py”,第157行,在反序列化程序中
data[field.attname]=model.\u meta.get\u field(field\u name).to\u python(field\u value)
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/db/models/fields/__init__.py”,第928行,在python中
params={'value':value},
django.core.exceptions.ValidationError:[“{'pk':无,'name':'Coworking Space'}”值必须是整数。“]
在处理上述异常期间,发生了另一个异常:
回溯(最近一次呼叫最后一次):
文件“manage.py”,第21行,在
main()
文件“manage.py”,第17行,主
从命令行(sys.argv)执行命令
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/core/management/_init__.py”,第371行,从命令行执行
utility.execute()
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/core/management/________.py”,第365行,执行
self.fetch_命令(子命令)。从_argv(self.argv)运行_
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site-packages/django/core/management/base.py”,第288行,从_argv运行
self.execute(*args,**cmd_选项)
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/core/management/base.py”,第335行,执行
输出=self.handle(*args,**选项)
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/core/management/commands/loaddata.py”,第72行,在handle中
self.loaddata(夹具标签)
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/core/management/commands/loaddata.py”,第113行,在loaddata中
自加载标签(夹具标签)
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/core/management/commands/loaddata.py”,第168行,装入标签
对于对象中的obj:
文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/core/serializers/pyyaml.py”,反序列化程序中的第73行
PythonDeserializer的产量(yaml.load(stream,Loader=SafeLoader),**选项)
反序列化程序中的文件“/Users/davea/Documents/workspace/chicommons/maps/env/lib/python3.7/site packages/django/core/serializers/python.py”,第159行
raise base.反序列化错误.WithData(e,d['model'],d.get('pk'),字段值)
django.core.serializers.base.Deserialization错误:安装fixture'/Users/davea/Documents/workspace/chicommons/maps/maps/maps/maps/fixtures/seed_data.yaml'时出现问题:[“{'pk':无,'name':'Coworking Space'}”值必须是整数]:(maps.coop:pk=1)字段\'u值为“{'pk无,'name':'Coworking Space'}”
有没有办法在seed_data.yaml文件中优雅地执行此操作?

解决方案: 按照以下步骤更新设备

- model: test_app.coop
  pk: 1
  fields:
    name: '1871'
    type:
    - Coworking Space
    enabled: true
    email: null
    web_site: ''
- model: test_app.coop
  pk: 2
  fields:
    name: '18715'
    type:
    - Coworking Space 2
    enabled: true
    email: null
    web_site: ''
- model: test_app.coop
  pk: 3
  fields:
    name: '187156'
    type:
    - Coworking Space 3
    enabled: true
    email: null
    web_site: ''
并在您的
CoopType
模型中添加自定义管理器

class CoopManager(models.Manager):

    def get_by_natural_key(self, name):
        return self.get_or_create(name=name)[0]


class CoopType(models.Model):
    name = models.CharField(max_length=200)

    objects = CoopManager()

    class Meta:
        unique_together = ("name",)
现在,当您加载装置时,它将创建
CoopType
对象(如果尚未存在),然后加载
Coop
模型

class CoopManager(models.Manager):

    def get_by_natural_key(self, name):
        return self.get_or_create(name=name)[0]


class CoopType(models.Model):
    name = models.CharField(max_length=200)

    objects = CoopManager()

    class Meta:
        unique_together = ("name",)
说明:这是负责反序列化对象的Django代码

# Handle FK fields
elif field.remote_field and isinstance(field.remote_field, models.ManyToOneRel):
    model = field.remote_field.model
    if field_value is not None:
        try:
            default_manager = model._default_manager
            field_name = field.remote_field.field_name
            if hasattr(default_manager, 'get_by_natural_key'):
                if hasattr(field_value, '__iter__') and not isinstance(field_value, six.text_type):
                    obj = default_manager.db_manager(db).get_by_natural_key(*field_value)
                    value = getattr(obj, field.remote_field.field_name)
                    # If this is a natural foreign key to an object that
                    # has a FK/O2O as the foreign key, use the FK value
                    if model._meta.pk.remote_field:
                        value = value.pk
                else:
                    value = model._meta.get_field(field_name).to_python(field_value)
                data[field.attname] = value
            else:
                data[field.attname] = model._meta.get_field(field_name).to_python(field_value)
        except Exception as e:
            raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value)
    else:
        data[field.attname] = None
来源:django.core.serializers.python第152行及以后

如您所见,如果模型中给出了
get\u by\u natural\u key
函数,并且fixture具有嵌套数据,那么它将调用
get\u by\u natural\u key
函数来获取对象。因此,在
get_by_natural_key
函数中,我们可以使用
get_或\u create
并返回实例

请检查
Coop
模型中的嵌套数据是否只有
args
而没有
kwargs
,因为Django代码在此函数中传递
args


PS:我不确定在
get\u by\u natural\u key
功能中使用
get\u或\u create
有多正确,但这是目前唯一有效的解决方案。

如下面的答案所述,看起来您有几个问题。除了格式化之外,Django还需要数据库中存在引用,以便成功地从fixture加载数据。其他一些解决方案怎么样,比如or,它们负责在参考模型中创建数据?我真的在挖掘您提供的这个解决方案——它似乎工作得很好。那么,如果我可以在我的模型上定义一个“get_by_natural_key”,那么在处理YAML文件时,依赖模型将被创建或更新?是的。请记住,YAML文件中定义的字段顺序很重要,在
get_by_natural_key
函数中,这些字段的定义顺序应该相同。此外,所有必填字段都应该存在于YAML文件中,否则在创建对象的过程中可能会引发错误。