Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a fixture out of QuerySet in django?

Django dumpdata command is broken because it does not support any reasonable way to narrow down the amount of data dumped. I need to create a fixture of various querysets (and I don't need to take care about dumping objects from outer models relations). Limiting the number of items for those querysets, like django-test-utils makefixture does is not sufficient. Tried to achieve this by using a proxy model with custom manager, but this approach does not work - dumpdata ommits proxy models (which is reasonable).

like image 420
pielgrzym Avatar asked Jul 20 '12 13:07

pielgrzym


People also ask

How do I create a fixture in Django?

You must create a directory in your app named fixtures and put your fixtures files there. You can write them in json or xml, one easy way to make them is to create some objects in the admin interface and then run manage.py dumpdata. That would dump the data from the objects you created into fixture files.

What is the use of QuerySet in Django?

A QuerySet is a collection of data from a database. A QuerySet is built up as a list of objects. QuerySets makes it easier to get the data you actually need, by allowing you to filter and order the data.

Where are Django fixtures stored?

You'll store this data in a fixtures directory inside your app. You can load data by calling manage.py loaddata <fixturename> , where <fixturename> is the name of the fixture file you've created. Each time you run loaddata , the data will be read from the fixture and reloaded into the database.

What does a QuerySet return?

Returns a QuerySet that returns dictionaries, rather than model instances, when used as an iterable. Each of those dictionaries represents an object, with the keys corresponding to the attribute names of model objects.


3 Answers

If dumpdata doesn't work, you can do the same through Django Serializing data.

from django.core import serializers
data = serializers.serialize("json", SomeModel.objects.all())

and then write the data on a file.

like image 194
Ahsan Avatar answered Sep 20 '22 09:09

Ahsan


The following steps will help in making the solution complete providing support to create a fixture of various querysets.

from django.core import serializers
from django.core.management.commands.dumpdata import sort_dependencies

app_list = {}

# Add all your querysets here. The key for the dictionary can be just a 
# unique dummy string (A safe hack after reading django code)
app_list['app1_name'] = FirstModel.objects.all()
app_list['app2_name'] = SecondModel.objects.all()

# The sort_dependencies will ensure that the models are sorted so that
# those with foreign keys are taken care. If SecondModel has a fk to FirstModel,
# then sort_dependencies will take care of the ordering in the json file so that
# FirstModel comes first in the fixture thus preventing ambiguity when reloading
data = serializers.serialize("json", sort_dependencies(app_list.items()))
f = open('output.json', 'w')
f.write(data)
f.close()

Now the output will be available in output.json file. To rebuild the models from the json file:

from django.core import serializers

for obj in serializers.deserialize('json', open('output.json').read()):
    obj.save()

EDIT: Strangely, the sort_dependencies didn't work as expected. So I ended up using python ordereddict and decided the order myself.

import collections

app_list = collections.OrderedDict()
like image 32
Bharathwaaj Avatar answered Sep 21 '22 09:09

Bharathwaaj


In case you want to save json data directly to a file, you can use:

from django.core import serializers


data = YourModel.objects.all()
with open("fixtures.json", "w") as out:
    serializers.serialize("json", data, stream=out)
like image 42
bilbohhh Avatar answered Sep 19 '22 09:09

bilbohhh