~ubuntu-branches/ubuntu/quantal/python-django/quantal-security

« back to all changes in this revision

Viewing changes to django/core/serializers/python.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2010-05-21 07:52:55 UTC
  • mfrom: (1.3.6 upstream)
  • mto: This revision was merged to the branch mainline in revision 28.
  • Revision ID: james.westby@ubuntu.com-20100521075255-ii78v1dyfmyu3uzx
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 
7
7
from django.conf import settings
8
8
from django.core.serializers import base
9
 
from django.db import models
 
9
from django.db import models, DEFAULT_DB_ALIAS
10
10
from django.utils.encoding import smart_unicode, is_protected_type
11
11
 
12
12
class Serializer(base.Serializer):
47
47
    def handle_fk_field(self, obj, field):
48
48
        related = getattr(obj, field.name)
49
49
        if related is not None:
50
 
            if field.rel.field_name == related._meta.pk.name:
51
 
                # Related to remote object via primary key
52
 
                related = related._get_pk_val()
 
50
            if self.use_natural_keys and hasattr(related, 'natural_key'):
 
51
                related = related.natural_key()
53
52
            else:
54
 
                # 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)
 
53
                if field.rel.field_name == related._meta.pk.name:
 
54
                    # Related to remote object via primary key
 
55
                    related = related._get_pk_val()
 
56
                else:
 
57
                    # Related to remote object via other field
 
58
                    related = smart_unicode(getattr(related, field.rel.field_name), strings_only=True)
 
59
        self._current[field.name] = related
57
60
 
58
61
    def handle_m2m_field(self, obj, field):
59
 
        if field.creates_table:
60
 
            self._current[field.name] = [smart_unicode(related._get_pk_val(), strings_only=True)
 
62
        if field.rel.through._meta.auto_created:
 
63
            if self.use_natural_keys and hasattr(field.rel.to, 'natural_key'):
 
64
                m2m_value = lambda value: value.natural_key()
 
65
            else:
 
66
                m2m_value = lambda value: smart_unicode(value._get_pk_val(), strings_only=True)
 
67
            self._current[field.name] = [m2m_value(related)
61
68
                               for related in getattr(obj, field.name).iterator()]
62
69
 
63
70
    def getvalue(self):
70
77
    It's expected that you pass the Python objects themselves (instead of a
71
78
    stream or a string) to the constructor
72
79
    """
 
80
    db = options.pop('using', DEFAULT_DB_ALIAS)
73
81
    models.get_apps()
74
82
    for d in object_list:
75
83
        # Look up the model and starting build a dict of data for it.
86
94
 
87
95
            # Handle M2M relations
88
96
            if field.rel and isinstance(field.rel, models.ManyToManyRel):
89
 
                m2m_convert = field.rel.to._meta.pk.to_python
90
 
                m2m_data[field.name] = [m2m_convert(smart_unicode(pk)) for pk in field_value]
 
97
                if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
 
98
                    def m2m_convert(value):
 
99
                        if hasattr(value, '__iter__'):
 
100
                            return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk
 
101
                        else:
 
102
                            return smart_unicode(field.rel.to._meta.pk.to_python(value))
 
103
                else:
 
104
                    m2m_convert = lambda v: smart_unicode(field.rel.to._meta.pk.to_python(v))
 
105
                m2m_data[field.name] = [m2m_convert(pk) for pk in field_value]
91
106
 
92
107
            # Handle FK fields
93
108
            elif field.rel and isinstance(field.rel, models.ManyToOneRel):
94
109
                if field_value is not None:
95
 
                    data[field.attname] = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value)
 
110
                    if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
 
111
                        if hasattr(field_value, '__iter__'):
 
112
                            obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value)
 
113
                            value = getattr(obj, field.rel.field_name)
 
114
                            # If this is a natural foreign key to an object that
 
115
                            # has a FK/O2O as the foreign key, use the FK value
 
116
                            if field.rel.to._meta.pk.rel:
 
117
                                value = value.pk
 
118
                        else:
 
119
                            value = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value)
 
120
                        data[field.attname] = value
 
121
                    else:
 
122
                        data[field.attname] = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value)
96
123
                else:
97
124
                    data[field.attname] = None
98
125