loading fixture with many-to-one relations in django

  • Last Update :
  • Techknowledgy :

But, each poll can be related to several choices:

{
   "pk": 4,
   "model": "polls.Choice",
   "fields": {
      "votes": 0,
      "poll": 2,
      "choice_text": "Meh."
   }
}, {
   "pk": 5,
   "model": "polls.Choice",
   "fields": {
      "votes": 0,
      "poll": 2,
      "choice_text": "Not so good."
   }
}

This is untested, but the polls/choices example referenced in this question might use natural keys like this (sorry, I prefer YAML and might have simplified the model to highlight the important parts):

-model: polls.Poll
fields:
   question: What time do you sleep ?
      -model : polls.Poll
   fields:
   question: What time do you get up ?

      -model : polls.Choice
   fields:
   choice_text: 10: 00
owner:
   -What time do you sleep ?
      -What time do you get up ?

Suggestion : 2

Models created with one-to-one relation as ​documented fail to produce loadable fixtures. , Fixtures created with dumpdata and then reloaded with loaddata fail with this error: ,Model saving was too aggressive about creating new parent class instances during deserialization. Raw save on a model now skips saving of the parent class. , The patch works for every case with the exception of when the parent model and the child model share the same pk field name.

Fixtures created with dumpdata and then reloaded with loaddata fail with this error:

ERROR: duplicate key violates unique constraint "App_model_pkey"

Models:

from django.db
import models

# Create your models here.
class Parent(models.Model):
   name = models.CharField(max_length = 60, unique = True)

class Child(Parent):
   parent = models.OneToOneField(Parent, parent_link = True)
number = models.IntegerField(max_length = 20)

Dumpdata

$. / manage.py dumpdata--format = json first > first / fixtures / test.json
$ cat first / fixtures / test.json[{
   "pk": 1,
   "model": "first.parent",
   "fields": {
      "name": "first1"
   }
}, {
   "pk": 1,
   "model": "first.child",
   "fields": {
      "name": "first1",
      "number": 2
   }
}]
$. / manage.py loaddata test
Installing json fixture 'test'
from '/home/zhaoz/programming/python/django_test/onetoone/../onetoone/first/fixtures'.
Problem installing fixture '/home/zhaoz/programming/python/django_test/onetoone/../onetoone/first/fixtures/test.json': column name is not unique

Suggestion : 3

Fixtures are initial data for the database. The most straightforward way when you have some existing data already is to use the command dumpdata,When using the loadddata without specifying a file, Django will look for a fixtures folder in your app or the list of directories provided in the FIXTURE_DIRS in settings, and use its content instead.,Get monthly updates about new articles, cheatsheets, and tricks.,This will create a json file which can be imported again by using

Fixtures are initial data for the database. The most straightforward way when you have some existing data already is to use the command dumpdata

 . / manage.py dumpdata > databasedump.json # full database
    . / manage.py dumpdata myapp > databasedump.json # only 1 app
    . / manage.py dumpdata myapp.mymodel > databasedump.json # only 1 model(table)

This will create a json file which can be imported again by using

. / manage.py loaddata databasedump.json

When using the loadddata without specifying a file, Django will look for a fixtures folder in your app or the list of directories provided in the FIXTURE_DIRS in settings, and use its content instead.

/myapp /
fixtures
myfixtures.json
morefixtures.xml

Fixtures YAML example:

-model: myapp.person
pk: 1
fields:
   first_name: John
last_name: Lennon -
   model: myapp.person
pk: 2
fields:
   first_name: Paul
last_name: McCartney

Fixtures XML example:

<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0">
   <object pk="1" model="myapp.person">
      <field type="CharField" name="first_name">John</field>
      <field type="CharField" name="last_name">Lennon</field>
   </object>
   <object pk="2" model="myapp.person">
      <field type="CharField" name="first_name">Paul</field>
      <field type="CharField" name="last_name">McCartney</field>
   </object>
</django-objects>

Suggestion : 4

July 2, 2019 by Chris Hranj

Let’s see some code already. We’ll use a simple data model borrowed from the Django Book to make it easier to explain our approach:

from django.db
import models

class Publisher(models.Model):
   name = models.TextField()

class Author(models.Model):
   first_name = models.TextField()
last_name = models.TextField()

class Book(models.Model):
   title = models.TextField()
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher, on_delete = models.PROTECT)
publication_date = models.DateField()
isbn = models.TextField()

Create a new file called factories.py in the same directory as your models (mysite/books/factories.py in this example) and add the following code:

import factory
from books.models
import Author, Book, Publisher

class PublisherFactory(factory.django.DjangoModelFactory):
   class Meta:
   model = Publisher

name = factory.Faker('company')

class AuthorFactory(factory.django.DjangoModelFactory):
   class Meta:
   model = Author

first_name = factory.Faker('first_name_female')
last_name = factory.Faker('last_name_female')

class BookFactory(factory.django.DjangoModelFactory):
   class Meta:
   model = Book

title = factory.Faker('sentence', nb_words = 4)
publisher = factory.SubFactory(PublisherFactory)
publication_date = factory.Faker('date_time')
isbn = factory.Faker('isbn13', separator = "-")

@factory.post_generation
def authors(self, create, extracted, ** kwargs):
   if not create:
   return

if extracted:
   for author in extracted:
   self.authors.add(author)

Example providers include addresses, credit cards, phone numbers, etc. (full list of faker providers here).

The factories in the code above use a number of different providers to match the type of data the model would contain. For example, the isbn field in the BookFactory above uses the isbn provider because it makes the most sense. You can play around with these factories in the django shell:

chranj @~/django-fixture-example/mysite$. / manage.py shell >>>
   from books.factories
import BookFactory
   >>>
   BookFactory.create() <
   Book: Book object(1) >

It’s more than likely that you’ll want to wipe the database before running a command like populatebooks, but for safety reasons this functionality should be optional. Note that django-admin actually has a flush command that does this, but using it can possibly have unintended consequences as it will wipe everything. Implementing a custom wipe command will give you complete control over what data gets dropped.

def add_arguments(self, parser):
   parser.add_argument(
      '--clean',
      help = 'Wipe existing data from the database before loading fixtures.',
      action = 'store_true',
      default = False,
   )

Add another argument just as we did above that looks as such:

parser.add_argument(
   '--seed',
   help = 'The initial seed to use when generating random data.',
   default = 'mysite',
   type = str,
)