Ticket #7052: lookup-dictionaries-for-fixtures-django-1.1.diff
File lookup-dictionaries-for-fixtures-django-1.1.diff, 35.4 KB (added by , 15 years ago) |
---|
-
django/db/models/base.py
378 378 379 379 pk = property(_get_pk_val, _set_pk_val) 380 380 381 def dump_related(self): 382 """ 383 Returns a Python object that is the serialization for this Model. 384 385 By default, this method just returns the primary key for this Model. 386 387 If 'Meta.dump_relation' is a tuple of field names, then this 388 method returns a dictionary of lookup fields for a QuerySet. 389 The tuple in 'dump_relation' should also appear in 390 'Meta.unique_together', so that only one object can be fetched 391 based on this lookup. 392 """ 393 dump_relation = getattr(self._meta, 'dump_relation', []) 394 if dump_relation: 395 return dict([(field_name, getattr(self, field_name)) 396 for field_name in dump_relation]) 397 return self._get_pk_val() 398 399 def load_related(cls, value): 400 """ 401 Returns the primary key for this Model, given a certain 'value'. 402 403 Use this in deserialization to handle objects that are created 404 automatically (e.g. auth.Permissions or contenttypes.ContentType). 405 406 'value' can be: 407 - None, 408 - a primary key itself, in string or integer form, 409 - a query dictionary, as generated by dump_related() above. 410 """ 411 if value is None: 412 return None 413 if hasattr(value, 'iteritems'): 414 # Case to handle query dictionaries 415 lookup = {} 416 for field_name, field_value in value.iteritems(): 417 field_name = str(field_name) 418 if hasattr(field_value, 'iteritems'): 419 # Turn subqueries into primary keys 420 field = cls._meta.get_field(field_name) 421 field_value = field.rel.to.load_related(field_value) 422 lookup[field_name] = field_value 423 return cls._default_manager.get(**lookup)._get_pk_val() 424 # Simple case for primary keys 425 return cls._meta.pk.to_python(value) 426 load_related = classmethod(load_related) 427 381 428 def serializable_value(self, field_name): 382 429 """ 383 430 Returns the value of the field name for this instance. If the field is -
django/db/models/options.py
19 19 get_verbose_name = lambda class_name: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', class_name).lower().strip() 20 20 21 21 DEFAULT_NAMES = ('verbose_name', 'db_table', 'ordering', 22 'unique_together', ' permissions', 'get_latest_by',22 'unique_together', 'dump_relation', 'permissions', 'get_latest_by', 23 23 'order_with_respect_to', 'app_label', 'db_tablespace', 24 24 'abstract', 'managed', 'proxy') 25 25 … … 32 32 self.db_table = '' 33 33 self.ordering = [] 34 34 self.unique_together = [] 35 self.dump_relation = [] 35 36 self.permissions = [] 36 37 self.object_name, self.app_label = None, app_label 37 38 self.get_latest_by = None -
django/core/serializers/xml_serializer.py
73 73 74 74 self.xml.endElement("field") 75 75 76 def _handle_related(self, related, depth): 77 if hasattr(related, 'iteritems'): 78 for name, value in related.iteritems(): 79 self.indent(depth) 80 self.xml.startElement("lookup", attrs={"name" : name}) 81 self._handle_related(value, depth+1) 82 self.xml.endElement("lookup") 83 if related: 84 self.indent(depth - 1) 85 else: 86 self.xml.characters(smart_unicode(related)) 87 88 76 89 def handle_fk_field(self, obj, field): 77 90 """ 78 91 Called to handle a ForeignKey (we need to treat them slightly … … 83 96 if related is not None: 84 97 if field.rel.field_name == related._meta.pk.name: 85 98 # Related to remote object via primary key 86 related = related._get_pk_val()99 self._handle_related(related.dump_related(), depth=3) 87 100 else: 88 101 # Related to remote object via other field 89 related = getattr(related, field.rel.field_name) 90 self.xml.characters(smart_unicode(related)) 102 self.xml.characters(smart_unicode(getattr(related, field.rel.field_name))) 91 103 else: 92 104 self.xml.addQuickElement("None") 93 105 self.xml.endElement("field") … … 101 113 if field.creates_table: 102 114 self._start_relational_field(field) 103 115 for relobj in getattr(obj, field.name).iterator(): 104 self.xml.addQuickElement("object", attrs={"pk" : smart_unicode(relobj._get_pk_val())}) 116 related = relobj.dump_related() 117 self.indent(3) 118 if hasattr(related, 'iteritems'): 119 self.xml.startElement("object", {}) 120 self._handle_related(related, depth=4) 121 self.xml.endElement("object") 122 else: 123 self.xml.addQuickElement("object", attrs={"pk" : smart_unicode(relobj._get_pk_val())}) 124 self.indent(2) 105 125 self.xml.endElement("field") 106 126 107 127 def _start_relational_field(self, field): … … 179 199 # Return a DeserializedObject so that the m2m data has a place to live. 180 200 return base.DeserializedObject(Model(**data), m2m_data) 181 201 202 def _handle_lookup_node(self, node): 203 # There are <lookup> nodes inside `node` 204 value = "" 205 lookup = {} 206 for n in node.childNodes: 207 if n.nodeType in (node.TEXT_NODE, node.CDATA_SECTION_NODE): 208 value += n.data.strip() 209 elif n.nodeName == "lookup": 210 lookup[str(n.getAttribute("name"))] = self._handle_lookup_node(n) 211 else: 212 raise base.DeserializationError("Unexpected <%s> node" % n.nodeName) 213 if value and lookup: 214 raise base.DeserializationError("Unexpected primary key inside <lookup> node") 215 return lookup or value 216 217 def _handle_object_node(self, node, field, m2m): 218 lookup = self._handle_lookup_node(node) 219 if m2m: 220 # Get the "pk" attribute from the <object> nodes 221 pk = node.getAttribute("pk") 222 elif not hasattr(lookup, 'iteritems'): 223 # `node` should only contain TextNode 224 pk = getInnerText(node).strip() 225 else: 226 # 'node' contains a lookup dictionary 227 pk = False 228 if not pk and not lookup: 229 if m2m: 230 raise base.DeserializationError("<object> node is missing the 'pk' attribute") 231 else: 232 raise base.DeserializationError("Must have either primary key or <lookup> nodes") 233 if m2m and pk: 234 return pk 235 elif pk: 236 return field.rel.to._meta.get_field(field.rel.field_name).to_python(pk) 237 else: 238 return field.rel.to.load_related(lookup) 239 182 240 def _handle_fk_field_node(self, node, field): 183 241 """ 184 242 Handle a <field> node for a ForeignKey 185 243 """ 186 244 # Check if there is a child node named 'None', returning None if so. 187 if node.getElementsByTagName( 'None'):245 if node.getElementsByTagName("None"): 188 246 return None 189 else: 190 return field.rel.to._meta.get_field(field.rel.field_name).to_python( 191 getInnerText(node).strip()) 247 return self._handle_object_node(node, field, m2m=False) 192 248 193 249 def _handle_m2m_field_node(self, node, field): 194 250 """ 195 251 Handle a <field> node for a ManyToManyField. 196 252 """ 197 return [ field.rel.to._meta.pk.to_python(198 c.getAttribute("pk"))199 for c in node.getElementsByTagName("object")]253 return [self._handle_object_node(c, field, m2m=True) 254 for c in node.getElementsByTagName("object")] 255 return result 200 256 201 257 def _get_model_from_node(self, node, attr): 202 258 """ -
django/core/serializers/python.py
9 9 from django.db import models 10 10 from django.utils.encoding import smart_unicode, is_protected_type 11 11 12 class RelationDepthExceeded(RuntimeError): 13 pass 14 12 15 class Serializer(base.Serializer): 13 16 """ 14 17 Serializes a QuerySet to basic Python objects. … … 44 47 else: 45 48 self._current[field.name] = field.value_to_string(obj) 46 49 50 def _handle_related(cls, related, depth, maxdepth): 51 if depth > maxdepth: 52 raise RelationDepthExceeded() 53 if hasattr(related, 'dump_related'): 54 related = related.dump_related() 55 if hasattr(related, 'iteritems'): 56 return dict([(k, cls._handle_related(v, depth+1, maxdepth)) 57 for k, v in related.iteritems()]) 58 return smart_unicode(related, strings_only=True) 59 _handle_related = classmethod(_handle_related) 60 61 def handle_related(cls, related, maxdepth=10): 62 try: 63 return cls._handle_related(related, depth=0, maxdepth=maxdepth) 64 except RelationDepthExceeded: 65 raise RelationDepthExceeded("%s has a circular dump dependency" % 66 related) 67 handle_related = classmethod(handle_related) 68 47 69 def handle_fk_field(self, obj, field): 48 70 related = getattr(obj, field.name) 49 71 if related is not None: 50 72 if field.rel.field_name == related._meta.pk.name: 51 73 # Related to remote object via primary key 52 related = related._get_pk_val()74 related = self.handle_related(related) 53 75 else: 54 76 # Related to remote object via other field 55 related = getattr(related, field.rel.field_name)56 self._current[field.name] = smart_unicode(related, strings_only=True)77 related = smart_unicode(getattr(related, field.rel.field_name), strings_only=True) 78 self._current[field.name] = related 57 79 58 80 def handle_m2m_field(self, obj, field): 59 81 if field.creates_table: 60 self._current[field.name] = [s mart_unicode(related._get_pk_val(), strings_only=True)82 self._current[field.name] = [self.handle_related(related) 61 83 for related in getattr(obj, field.name).iterator()] 62 84 63 85 def getvalue(self): … … 86 108 87 109 # Handle M2M relations 88 110 if field.rel and isinstance(field.rel, models.ManyToManyRel): 89 m2m_convert = field.rel.to. _meta.pk.to_python90 m2m_data[field.name] = [m2m_convert( smart_unicode(pk)) for pk in field_value]111 m2m_convert = field.rel.to.load_related 112 m2m_data[field.name] = [m2m_convert(pk) for pk in field_value] 91 113 92 114 # Handle FK fields 93 115 elif field.rel and isinstance(field.rel, models.ManyToOneRel): 94 if field_value is not None: 116 if field_value is None: 117 data[field.attname] = None 118 elif field.rel.field_name == field.rel.to._meta.pk.name: 119 data[field.attname] = field.rel.to.load_related(field_value) 120 else: 95 121 data[field.attname] = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value) 96 else:97 data[field.attname] = None98 122 99 123 # Handle all other fields 100 124 else: -
django/contrib/contenttypes/models.py
76 76 db_table = 'django_content_type' 77 77 ordering = ('name',) 78 78 unique_together = (('app_label', 'model'),) 79 dump_relation = unique_together[0] 79 80 80 81 def __unicode__(self): 81 82 return self.name 82 83 84 def load_related(cls, value): 85 try: 86 app_label = value['app_label'] 87 model = value['model'] 88 except (KeyError, TypeError): 89 return super(ContentType, cls).load_related(value) 90 return cls.objects.get_for_model(models.get_model(app_label, model))._get_pk_val() 91 load_related = classmethod(load_related) 92 83 93 def model_class(self): 84 94 "Returns the Python model class for this type of content." 85 95 from django.db import models -
django/contrib/auth/models.py
68 68 verbose_name = _('permission') 69 69 verbose_name_plural = _('permissions') 70 70 unique_together = (('content_type', 'codename'),) 71 dump_relation = unique_together[0] 71 72 ordering = ('content_type__app_label', 'codename') 72 73 73 74 def __unicode__(self): -
tests/modeltests/fixtures/fixtures/fixture6.json
1 [ 2 { 3 "pk": "1", 4 "model": "fixtures.tag", 5 "fields": { 6 "name": "copyright", 7 "tagged_type": { 8 "app_label": "fixtures", 9 "model": "article" 10 }, 11 "tagged_id": "3" 12 } 13 }, 14 { 15 "pk": "2", 16 "model": "fixtures.tag", 17 "fields": { 18 "name": "law", 19 "tagged_type": { 20 "app_label": "fixtures", 21 "model": "article" 22 }, 23 "tagged_id": "3" 24 } 25 } 26 ] -
tests/modeltests/fixtures/fixtures/fixture8.json
1 [ 2 { 3 "pk": "1", 4 "model": "fixtures.visa", 5 "fields": { 6 "name": "Django Reinhardt", 7 "permissions": [ 8 { 9 "codename": "add_user", 10 "content_type": { 11 "model": "user", 12 "app_label": "auth" 13 } 14 }, 15 { 16 "codename": "change_user", 17 "content_type": { 18 "model": "user", 19 "app_label": "auth" 20 } 21 }, 22 { 23 "codename": "delete_user", 24 "content_type": { 25 "model": "user", 26 "app_label": "auth" 27 } 28 } 29 ] 30 } 31 }, 32 { 33 "pk": "2", 34 "model": "fixtures.visa", 35 "fields": { 36 "name": "Stephane Grappelli", 37 "permissions": [ 38 { 39 "codename": "add_user", 40 "content_type": { 41 "model": "user", 42 "app_label": "auth" 43 } 44 } 45 ] 46 } 47 }, 48 { 49 "pk": "3", 50 "model": "fixtures.visa", 51 "fields": { 52 "name": "Prince", 53 "permissions": [] 54 } 55 } 56 ] -
tests/modeltests/fixtures/fixtures/fixture7.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <django-objects version="1.0"> 3 <object pk="2" model="fixtures.tag"> 4 <field type="CharField" name="name">legal</field> 5 <field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"> 6 <lookup name="app_label">fixtures</lookup> 7 <lookup name="model">article</lookup> 8 </field> 9 <field type="PositiveIntegerField" name="tagged_id">3</field> 10 </object> 11 <object pk="3" model="fixtures.tag"> 12 <field type="CharField" name="name">django</field> 13 <field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"> 14 <lookup name="app_label">fixtures</lookup> 15 <lookup name="model">article</lookup> 16 </field> 17 <field type="PositiveIntegerField" name="tagged_id">4</field> 18 </object> 19 <object pk="4" model="fixtures.tag"> 20 <field type="CharField" name="name">world domination</field> 21 <field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"> 22 <lookup name="app_label">fixtures</lookup> 23 <lookup name="model">article</lookup> 24 </field> 25 <field type="PositiveIntegerField" name="tagged_id">4</field> 26 </object> 27 </django-objects> -
tests/modeltests/fixtures/fixtures/fixture9.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <django-objects version="1.0"> 3 <object pk="2" model="fixtures.visa"> 4 <field type="CharField" name="name">Stephane Grappelli</field> 5 <field to="auth.permission" name="permissions" rel="ManyToManyRel"> 6 <object> 7 <lookup name="codename">add_user</lookup> 8 <lookup name="content_type"> 9 <lookup name="model">user</lookup> 10 <lookup name="app_label">auth</lookup> 11 </lookup> 12 </object> 13 <object> 14 <lookup name="codename">delete_user</lookup> 15 <lookup name="content_type"> 16 <lookup name="model">user</lookup> 17 <lookup name="app_label">auth</lookup> 18 </lookup> 19 </object> 20 </field> 21 </object> 22 <object pk="3" model="fixtures.visa"> 23 <field type="CharField" name="name">Artist formerly known as "Prince"</field> 24 <field to="auth.permission" name="permissions" rel="ManyToManyRel"></field> 25 </object> 26 </django-objects> -
tests/modeltests/fixtures/models.py
8 8 ``FIXTURE_DIRS`` setting. 9 9 """ 10 10 11 from django.contrib.auth.models import Permission 12 from django.contrib.contenttypes import generic 13 from django.contrib.contenttypes.models import ContentType 11 14 from django.db import models 12 15 from django.conf import settings 13 16 … … 31 34 class Meta: 32 35 ordering = ('-pub_date', 'headline') 33 36 37 class Blog(models.Model): 38 name = models.CharField(max_length=100) 39 featured = models.ForeignKey(Article, related_name='fixtures_featured_set') 40 articles = models.ManyToManyField(Article, blank=True, 41 related_name='fixtures_articles_set') 42 43 def __unicode__(self): 44 return self.name 45 46 47 class Tag(models.Model): 48 name = models.CharField(max_length=100) 49 tagged_type = models.ForeignKey(ContentType, related_name="fixtures_tag_set") 50 tagged_id = models.PositiveIntegerField(default=0) 51 tagged = generic.GenericForeignKey(ct_field='tagged_type', 52 fk_field='tagged_id') 53 54 def __unicode__(self): 55 return '<%s: %s> tagged "%s"' % (self.tagged.__class__.__name__, 56 self.tagged, self.name) 57 58 class Visa(models.Model): 59 name = models.CharField(max_length=100) 60 permissions = models.ManyToManyField(Permission, blank=True) 61 62 def __unicode__(self): 63 return '%s %s' % (self.name, 64 ', '.join(p.name for p in self.permissions.all())) 65 34 66 __test__ = {'API_TESTS': """ 35 67 >>> from django.core import management 36 68 >>> from django.db.models import get_app … … 90 122 >>> Article.objects.all() 91 123 [<Article: XML identified as leading cause of cancer>, <Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker on TV is great!>, <Article: Python program becomes self aware>] 92 124 125 # Load fixture 6, JSON file with dynamic ContentType fields. Testing ManyToOne. 126 >>> management.call_command('loaddata', 'fixture6.json', verbosity=0) 127 >>> Tag.objects.all() 128 [<Tag: <Article: Copyright is fine the way it is> tagged "copyright">, <Tag: <Article: Copyright is fine the way it is> tagged "law">] 129 130 # Load fixture 7, XML file with dynamic ContentType fields. Testing ManyToOne. 131 >>> management.call_command('loaddata', 'fixture7.xml', verbosity=0) 132 >>> Tag.objects.all() 133 [<Tag: <Article: Copyright is fine the way it is> tagged "copyright">, <Tag: <Article: Copyright is fine the way it is> tagged "legal">, <Tag: <Article: Django conquers world!> tagged "django">, <Tag: <Article: Django conquers world!> tagged "world domination">] 134 135 # Load fixture 8, JSON file with dynamic Permission fields. Testing ManyToMany. 136 >>> management.call_command('loaddata', 'fixture8.json', verbosity=0) 137 >>> Visa.objects.all() 138 [<Visa: Django Reinhardt Can add user, Can change user, Can delete user>, <Visa: Stephane Grappelli Can add user>, <Visa: Prince >] 139 140 # Load fixture 9, XML file with dynamic Permission fields. Testing ManyToMany. 141 >>> management.call_command('loaddata', 'fixture9.xml', verbosity=0) 142 >>> Visa.objects.all() 143 [<Visa: Django Reinhardt Can add user, Can change user, Can delete user>, <Visa: Stephane Grappelli Can add user, Can delete user>, <Visa: Artist formerly known as "Prince" >] 144 93 145 # Load a fixture that doesn't exist 94 146 >>> management.call_command('loaddata', 'unknown.json', verbosity=0) 95 147 96 148 # object list is unaffected 97 149 >>> Article.objects.all() 98 150 [<Article: XML identified as leading cause of cancer>, <Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker on TV is great!>, <Article: Python program becomes self aware>] 151 152 # Dump the current contents of the database as a JSON fixture 153 >>> management.call_command('dumpdata', 'fixtures', format='json') 154 [{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 5, "model": "fixtures.article", "fields": {"headline": "XML identified as leading cause of cancer", "pub_date": "2006-06-16 16:00:00"}}, {"pk": 4, "model": "fixtures.article", "fields": {"headline": "Django conquers world!", "pub_date": "2006-06-16 15:00:00"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Copyright is fine the way it is", "pub_date": "2006-06-16 14:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker on TV is great!", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.tag", "fields": {"tagged_type": {"model": "article", "app_label": "fixtures"}, "name": "copyright", "tagged_id": 3}}, {"pk": 2, "model": "fixtures.tag", "fields": {"tagged_type": {"model": "article", "app_label": "fixtures"}, "name": "legal", "tagged_id": 3}}, {"pk": 3, "model": "fixtures.tag", "fields": {"tagged_type": {"model": "article", "app_label": "fixtures"}, "name": "django", "tagged_id": 4}}, {"pk": 4, "model": "fixtures.tag", "fields": {"tagged_type": {"model": "article", "app_label": "fixtures"}, "name": "world domination", "tagged_id": 4}}, {"pk": 1, "model": "fixtures.visa", "fields": {"name": "Django Reinhardt", "permissions": [{"codename": "add_user", "content_type": {"model": "user", "app_label": "auth"}}, {"codename": "change_user", "content_type": {"model": "user", "app_label": "auth"}}, {"codename": "delete_user", "content_type": {"model": "user", "app_label": "auth"}}]}}, {"pk": 2, "model": "fixtures.visa", "fields": {"name": "Stephane Grappelli", "permissions": [{"codename": "add_user", "content_type": {"model": "user", "app_label": "auth"}}, {"codename": "delete_user", "content_type": {"model": "user", "app_label": "auth"}}]}}, {"pk": 3, "model": "fixtures.visa", "fields": {"name": "Artist formerly known as \\"Prince\\"", "permissions": []}}] 155 156 # Dump the current contents of the database as an XML fixture 157 >>> management.call_command('dumpdata', 'fixtures', format='xml') 158 <?xml version="1.0" encoding="utf-8"?> 159 <django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="5" model="fixtures.article"><field type="CharField" name="headline">XML identified as leading cause of cancer</field><field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field></object><object pk="4" model="fixtures.article"><field type="CharField" name="headline">Django conquers world!</field><field type="DateTimeField" name="pub_date">2006-06-16 15:00:00</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Copyright is fine the way it is</field><field type="DateTimeField" name="pub_date">2006-06-16 14:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker on TV is great!</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><lookup name="model">article</lookup><lookup name="app_label">fixtures</lookup></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">legal</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><lookup name="model">article</lookup><lookup name="app_label">fixtures</lookup></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="3" model="fixtures.tag"><field type="CharField" name="name">django</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><lookup name="model">article</lookup><lookup name="app_label">fixtures</lookup></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="4" model="fixtures.tag"><field type="CharField" name="name">world domination</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><lookup name="model">article</lookup><lookup name="app_label">fixtures</lookup></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="1" model="fixtures.visa"><field type="CharField" name="name">Django Reinhardt</field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><lookup name="codename">add_user</lookup><lookup name="content_type">user</lookup></object><object><lookup name="codename">change_user</lookup><lookup name="content_type">user</lookup></object><object><lookup name="codename">delete_user</lookup><lookup name="content_type">user</lookup></object></field></object><object pk="2" model="fixtures.visa"><field type="CharField" name="name">Stephane Grappelli</field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><lookup name="codename">add_user</lookup><lookup name="content_type">user</lookup></object><object><lookup name="codename">delete_user</lookup><lookup name="content_type">user</lookup></object></field></object><object pk="3" model="fixtures.visa"><field type="CharField" name="name">Artist formerly known as "Prince"</field><field to="auth.permission" name="permissions" rel="ManyToManyRel"></field></object></django-objects> 99 160 """} 100 161 101 162 # Database flushing does not work on MySQL with the default storage engine … … 159 220 >>> management.call_command('loaddata', 'fixture5', verbosity=0) # doctest: +ELLIPSIS 160 221 Multiple fixtures named 'fixture5' in '...fixtures'. Aborting. 161 222 223 >>> management.call_command('flush', verbosity=0, interactive=False) 224 225 # Load back in fixture 1, we need the articles from it 226 >>> management.call_command('loaddata', 'fixture1', verbosity=0) 227 228 # Try to load fixture 6 using format discovery 229 >>> management.call_command('loaddata', 'fixture6', verbosity=0) 230 >>> Tag.objects.all() 231 [<Tag: <Article: Time to reform copyright> tagged "copyright">, <Tag: <Article: Time to reform copyright> tagged "law">] 232 233 # Dump the current contents of the database as a JSON fixture 234 >>> management.call_command('dumpdata', 'fixtures', format='json') 235 [{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.tag", "fields": {"tagged_type": {"model": "article", "app_label": "fixtures"}, "name": "copyright", "tagged_id": 3}}, {"pk": 2, "model": "fixtures.tag", "fields": {"tagged_type": {"model": "article", "app_label": "fixtures"}, "name": "law", "tagged_id": 3}}] 236 237 # Dump the current contents of the database as an XML fixture 238 >>> management.call_command('dumpdata', 'fixtures', format='xml') 239 <?xml version="1.0" encoding="utf-8"?> 240 <django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Time to reform copyright</field><field type="DateTimeField" name="pub_date">2006-06-16 13:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker has no place on ESPN</field><field type="DateTimeField" name="pub_date">2006-06-16 12:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><lookup name="model">article</lookup><lookup name="app_label">fixtures</lookup></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">law</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><lookup name="model">article</lookup><lookup name="app_label">fixtures</lookup></field><field type="PositiveIntegerField" name="tagged_id">3</field></object></django-objects> 162 241 """ 163 242 164 243 from django.test import TestCase -
docs/topics/db/queries.txt
817 817 # THIS WILL RAISE A FieldError 818 818 >>> Entry.objects.update(headline=F('blog__name')) 819 819 820 .. _related-objects: 821 820 822 Related objects 821 823 =============== 822 824 -
docs/ref/models/instances.txt
413 413 More details on named URL patterns are in the :ref:`URL dispatch documentation 414 414 <topics-http-urls>`. 415 415 416 .. _lookup-dictionary: 417 418 Serializing and deserializing auto-created objects 419 ================================================== 420 421 .. versionadded:: development 422 423 In certain circumstances, a model needs to create objects based on 424 other models in an application. For instance, whenever a 425 :class:`~django.db.models.Model` is defined, Django will eventually 426 create corresponding :class:`~django.contrib.auth.models.Permission` 427 objects. 428 429 Models with a :ref:`forward relationship<related-objects>` to 430 automatically created objects, such as ``Permission``, need help when 431 serializing and deserializing these references. This happens whenever 432 you create or load a fixture. Since ``Permission`` objects can be 433 created in any order, they cannot be reliably referenced by their 434 primary keys during serialization. Instead, they are referenced by a 435 lookup dictionary. 436 437 ``dump_relation`` 438 ----------------- 439 440 When writing a class that will be referenced by a lookup dictionary, 441 you should specify :attr:`Options.dump_relation`. For more 442 information, see the :ref:`model option reference<ref-models-options>`. 443 444 Methods for handling custom relations 445 ------------------------------------- 446 447 If :attr:`dump_related` is too inflexible for a particular model, you 448 can override the following methods to serialize and deserialize custom 449 lookup dictionaries. 450 451 .. method:: Model.dump_related() 452 453 Defines a ``dump_related()`` method to tell Django how to build a lookup 454 dictionary for this model. For example:: 455 456 def dump_related(self): 457 return {'year': self.year, 'month': self.month, 'day': self.day} 458 459 Django uses this when serializing objects, which typically happens when 460 :djadmin:`dumpdata<dumpdata>` is run. 461 462 .. method:: Model.load_related(value) 463 464 Defines a ``load_related()`` method to tell Django how to find the 465 primary key for this model, when deserializing. It returns the primary 466 key associated with ``value``, which was created by 467 :meth:`Model.dump_related()`. For example:: 468 469 def load_related(cls, value): 470 year, month, day = value.year, value.month, value.day 471 return cls.objects.get(year=year, month=month, day=day).id 472 load_related = classmethod(load_related) 473 474 Django uses this method when deserializing objects which have 475 :class:`~django.db.models.ForeignKey`, 476 :class:`~django.db.models.ManyToManyField`, or 477 :class:`~django.db.models.OneToOneField` relationships to objects that 478 were created automatically, such as 479 :class:`~django.contrib.auth.models.Permission` or 480 :class:`~django.contrib.contenttypes.models.ContentType` objects. This 481 typically happens when :djadmin:`loaddata<loaddata>` is run. 482 416 483 Extra instance methods 417 484 ====================== 418 485 -
docs/ref/models/options.txt
60 60 The name of the database tablespace to use for the model. If the backend doesn't 61 61 support tablespaces, this option is ignored. 62 62 63 ``dump_relation`` 64 ----------------- 65 66 .. attribute:: Options.dump_relation 67 68 .. versionadded:: development 69 70 Set of field names that, taken together, that define a :ref:`lookup 71 dictionary<lookup-dictionary>` for serialization:: 72 73 dump_relation = ("driver", "restaurant") 74 75 It's used by :meth:`Model.dump_related()` to build a lookup dictionary 76 when serializing a reference to this model. 77 78 Since these fields are used to fetch a single object, they should also 79 appear in :attr:`~Options.unique_together`. 80 63 81 ``get_latest_by`` 64 82 ----------------- 65 83