Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #13030 -- Corrected natural key deserialization to subclasses. …

…Thanks to yishaibeeri for the report and test case.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12804 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 10de2a837f580d76a480a9e0b974cecd2d1d26cb 1 parent be8a1f6
@freakboy3742 freakboy3742 authored
View
4 django/core/serializers/python.py
@@ -111,6 +111,10 @@ def m2m_convert(value):
if hasattr(field_value, '__iter__'):
obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value)
value = getattr(obj, field.rel.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 field.rel.to._meta.pk.rel:
+ value = value.pk
else:
value = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value)
data[field.attname] = value
View
4 django/core/serializers/xml_serializer.py
@@ -221,6 +221,10 @@ def _handle_fk_field_node(self, node, field):
field_value = [getInnerText(k).strip() for k in keys]
obj = field.rel.to._default_manager.db_manager(self.db).get_by_natural_key(*field_value)
obj_pk = getattr(obj, field.rel.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 field.rel.to._meta.pk.rel:
+ obj_pk = obj_pk.pk
else:
# Otherwise, treat like a normal PK
field_value = getInnerText(node).strip()
View
18 tests/regressiontests/fixtures_regress/fixtures/nk-inheritance.json
@@ -0,0 +1,18 @@
+[
+ {
+ "pk": 1,
+ "model": "fixtures_regress.nkchild",
+ "fields": {
+ "data": "apple"
+ }
+ },
+ {
+ "pk": 1,
+ "model": "fixtures_regress.reftonkchild",
+ "fields": {
+ "text": "my text",
+ "nk_fk" : ["apple"],
+ "nk_m2m": [["apple"]]
+ }
+ }
+]
View
23 tests/regressiontests/fixtures_regress/fixtures/nk-inheritance2.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<django-objects version="1.0">
+ <object pk="2" model="fixtures_regress.parent">
+ <field type="CharField" name="name">james</field>
+ </object>
+ <object pk="2" model="fixtures_regress.nkchild">
+ <field type="CharField" name="data">banana</field>
+ </object>
+ <object pk="2" model="fixtures_regress.reftonkchild">
+ <field type="CharField" name="text">other text</field>
+ <field to="fixtures_regress.nkchild" name="nk_fk" rel="ManyToOneRel">
+ <natural>apple</natural>
+ </field>
+ <field to="fixtures_regress.nkchild" name="nk_m2m" rel="ManyToManyRel">
+ <object>
+ <natural>banana</natural>
+ </object>
+ <object>
+ <natural>apple</natural>
+ </object>
+ </field>
+ </object>
+</django-objects>
View
52 tests/regressiontests/fixtures_regress/models.py
@@ -52,6 +52,9 @@ def __init__(self, *args, **kwargs):
class Parent(models.Model):
name = models.CharField(max_length=10)
+ class Meta:
+ ordering = ('id',)
+
class Child(Parent):
data = models.CharField(max_length=10)
@@ -130,6 +133,32 @@ def __unicode__(self):
', '.join(s.name for s in self.stores.all())
)
+class NKManager(models.Manager):
+ def get_by_natural_key(self, data):
+ return self.get(data=data)
+
+class NKChild(Parent):
+ data = models.CharField(max_length=10, unique=True)
+ objects = NKManager()
+
+ def natural_key(self):
+ return self.data
+
+ def __unicode__(self):
+ return u'NKChild %s:%s' % (self.name, self.data)
+
+class RefToNKChild(models.Model):
+ text = models.CharField(max_length=10)
+ nk_fk = models.ForeignKey(NKChild, related_name='ref_fks')
+ nk_m2m = models.ManyToManyField(NKChild, related_name='ref_m2ms')
+
+ def __unicode__(self):
+ return u'%s: Reference to %s [%s]' % (
+ self.text,
+ self.nk_fk,
+ ', '.join(str(o) for o in self.nk_m2m.all())
+ )
+
# ome models with pathological circular dependencies
class Circle1(models.Model):
name = models.CharField(max_length=255)
@@ -245,6 +274,27 @@ def natural_key(self):
>>> management.call_command('loaddata', 'model-inheritance.json', verbosity=0)
###############################################
+# Test for ticket #13030 -- natural keys deserialize with fk to inheriting model
+
+# load data with natural keys
+>>> management.call_command('loaddata', 'nk-inheritance.json', verbosity=0)
+
+>>> NKChild.objects.get(pk=1)
+<NKChild: NKChild fred:apple>
+
+>>> RefToNKChild.objects.get(pk=1)
+<RefToNKChild: my text: Reference to NKChild fred:apple [NKChild fred:apple]>
+
+# ... and again in XML
+>>> management.call_command('loaddata', 'nk-inheritance2.xml', verbosity=0)
+
+>>> NKChild.objects.get(pk=2)
+<NKChild: NKChild james:banana>
+
+>>> RefToNKChild.objects.get(pk=2)
+<RefToNKChild: other text: Reference to NKChild fred:apple [NKChild fred:apple, NKChild james:banana]>
+
+###############################################
# Test for ticket #7572 -- MySQL has a problem if the same connection is
# used to create tables, load data, and then query over that data.
# To compensate, we close the connection after running loaddata.
@@ -279,7 +329,7 @@ def natural_key(self):
[{"pk": 1, "model": "fixtures_regress.animal", "fields": {"count": 3, "weight": 1.2, "name": "Lion", "latin_name": "Panthera leo"}}, {"pk": 2, "model": "fixtures_regress.animal", "fields": {"count": 2, "weight": 2.2, "name": "Platypus", "latin_name": "Ornithorhynchus anatinus"}}, {"pk": 10, "model": "fixtures_regress.animal", "fields": {"count": 42, "weight": 1.2, "name": "Emu", "latin_name": "Dromaius novaehollandiae"}}]
###############################################
-# Regression for #11428 - Proxy models aren't included when you dumpdata
+# Regression for #11428 - Proxy models aren't included when you dumpdata
# Flush out the database first
>>> management.call_command('reset', 'fixtures_regress', interactive=False, verbosity=0)
Please sign in to comment.
Something went wrong with that request. Please try again.