I realise it's more than a year since this question was asked, however you (or someone else) might like to know that I was able to use fixtures in testing a model with generic foreign key to ContentType. There's a caveat to this though, which is that I had to hard-code the content_type_id in the test fixtures, and that is probably a bit unstable in terms of order in which ContentTypes are created in the database. (I'm beginning to re-write my tests with factory_boy for the reasons @Lara mentioned)
I am currently using Django 1.8.3, Python 2.7.9.
The key feature seems to be the order of loading fixtures. In my tests.py I have:
tests.py:
class MyModelViewTests(TestCase):
fixtures = [
'auth_user.json',
'gfk_model.json',
'my_model.json',
]
def test_something(self):
# your tests
Above, the gfk_model.json contains fixtures for the model containing the generic foreign key to ContentType. The my_model.json contains the fixtures for whatever model your Django project or app needs. So I instantiate the model instances containing generic foreign keys first. It's true that their object_id entries reference database rows for my_model which don't quite exist yet, but will exist as soon as the my_model.json fixtures are loaded.
MyModel/models.py
class MyModel(models.Model):
book_title = models.TextField()
book_isbn = models.CharField(max_length=13)
GFKModel/models.py
class GFKModel(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
your_field = models.TextField()
If I'm associating the generic foreign key with one particular ContentType, then I can get the id of the content type from the SQL database or content_type_id = ContentType.objects.get_for_model(MyModel).pk
, executed in a django shell (python manage.py shell
). I then hardcoded (yukky I know!) the id thus obtained (13 in my case) in my fixtures.
So, finally the fixtures (obtained from dumpdata, then edited) look something like this
gfk_model.json
[
{
"fields": {
"your_field": "Stuff you need to associate with my_model",
"object_id": 1,
"content_type": 13,
},
"model": "myapp.gfk_model",
"pk": 1
},
{
"fields": {
"your_field": "Stuff you need to associate with my_model",
"object_id": 2,
"content_type": 13,
},
"model": "gfk_app.gfk_model",
"pk": 2
}
]
my_model.json
[
{
"pk": 1,
"model": "myapp.my_model",
"fields": {
"book_name": "How to bath your cat",
"book_isbn": "123456",
}
},
{
"pk": 2,
"model": "myapp.my_model",
"fields": {
"book_name": "How About Wednesday?",
"book_isbn": "654321",
}
}
]
In the gfk_model.json the object_id of 1 and 2 correspond to the PKs 1, 2 of the my_model.json respectively. I've provided PKs for the gkf_model instances too (although possibly I don't need to, haven't tried removing them).
All in all, it was actually much quicker to get it working than to write this post!
It's also pretty straightforward to get GFK tests working just by using the ORM in the test setUp(). Also fine with factory_boy too.
If you've got several different ContentTypes, and especially if they are likely to change their pk in the contenttypes table, I don't think fixtures are going to be very successful.