Django具有特定数据

时间:2018-02-20 13:35:53

标签: django fixtures django-fixtures

我有一个包含3个模型的应用程序,它们以父子方式相互引用:

class A(Model):
    # ...

class B(Model):
    a = ForeignKey(A)
    # ...

class C(Model):
    b = ForeignKey(B)
    # ...

在我的生产数据库中,我有数百个A类对象,其下面有数千个子对象。我现在想要仅为(特定)少数对象创建一个夹具。如果我运行此命令,我的输出将变得巨大:

python manage.py dumpdata ca_myapp -o /tmp/my_app_dump.json

但是,当我使用此命令限制输出时:

python manage.py dumpdata ca_myapp.A -o /tmp/myapp_dump.json --pks pk1, pk2, pk3

然后只反序列化A对象,而不是它们的子代。如何轻松地创建包含少数对象及其子项的fixture文件?

2 个答案:

答案 0 :(得分:1)

来自Django documentation regarding dumpdata

dumpdata

  

django-admin dumpdata [app_label[.ModelName] [app_label[.ModelName]...]]

所以在你的情况下

python manage.py dumpdata ca_myapp.A ca_myapp.B ca_myapp.C

其他方式是使用exclude

  --exclude EXCLUDE,-e EXCLUDE      

防止转储特定的应用程序或模型(以app_label.ModelName的形式指定)。如果   如果指定了型号名称,则输出将仅限于该型号,   而不是整个应用程序。您还可以混合应用程序名称   和型号名称。

     

如果要排除多个应用程序,请传递--exclude以上   一旦

如果我没有正确理解问题,并且您在询问是否可以选择几个pks并遵循他们之间目前无法使用dumpdata的关系, 但是你可以轻松准备你的数据库来保存必要的数据。

答案 1 :(得分:0)

我现在写了一个Django命令,首先检查我想要获取哪些pks,以及他们拥有哪些子代,以获取所有相关对象。

import logging
import os

from django.core.management import BaseCommand, call_command

logger = logging.getLogger(__name__)

A = {'pk1', 'pk2', 'pk3'}

class Command(BaseCommand):
    def __init__(self, stdout=None, stderr=None, no_color=False):
        super().__init__(stdout, stderr, no_color)
        self.settings = None
        self.a = set()

    @property
    def tmp_dir(self):
        return '/tmp'

    def handle(self, *args, **options):
        self.settings = options.get('settings')

        # TODO: Make list of A an optional argument
        a_pks = A
        self.dump_objects('ca_myapp.A', pks=a_pks)

        b_pks = B.objects.filter(a_id__in=a_pks).values_list('pk', flat=True)
        self.dump_objects('ca_myapp.B', pks=b_pks)

        c_pks = C.objects.filter(b_id__in=b_pks).values_list('pk', flat=True)
        self.dump_objects('ca_myapp.C', pks=c_pks)

    def dump_objects(self, model_name: str, pks: set):
        if pks:
            call_command('dumpdata', model_name,
                         '--pks', ','.join(pks),
                         '--indent', '2',
                         '-o', os.path.join(self.tmp_dir, '{}.json'.format(model_name)),
                         '--settings', self.settings)
        else:
            logger.warning('No objects for model {} found'.format(model_name))