2007-09-15 13:32:29 +08:00
# -*- coding: utf-8 -*-
2006-06-29 00:00:37 +08:00
"""
2007-12-02 05:18:45 +08:00
42. Serialization
2006-06-29 00:00:37 +08:00
2008-08-12 22:15:38 +08:00
` ` django . core . serializers ` ` provides interfaces to converting Django
` ` QuerySet ` ` objects to and from " flat " data ( i . e . strings ) .
2006-06-29 00:00:37 +08:00
"""
2009-02-12 04:13:17 +08:00
try :
from decimal import Decimal
except ImportError :
from django . utils . _decimal import Decimal # Python 2.3 fallback
2006-06-29 00:00:37 +08:00
from django . db import models
class Category ( models . Model ) :
2007-08-05 13:14:46 +08:00
name = models . CharField ( max_length = 20 )
2006-06-29 00:00:37 +08:00
class Meta :
ordering = ( ' name ' , )
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
def __unicode__ ( self ) :
2006-06-29 00:00:37 +08:00
return self . name
class Author ( models . Model ) :
2007-08-05 13:14:46 +08:00
name = models . CharField ( max_length = 20 )
2006-06-29 00:00:37 +08:00
class Meta :
ordering = ( ' name ' , )
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
def __unicode__ ( self ) :
2006-06-29 00:00:37 +08:00
return self . name
class Article ( models . Model ) :
author = models . ForeignKey ( Author )
2007-08-05 13:14:46 +08:00
headline = models . CharField ( max_length = 50 )
2006-06-29 00:00:37 +08:00
pub_date = models . DateTimeField ( )
categories = models . ManyToManyField ( Category )
class Meta :
ordering = ( ' pub_date ' , )
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
def __unicode__ ( self ) :
2006-06-29 00:00:37 +08:00
return self . headline
2007-01-27 21:42:51 +08:00
class AuthorProfile ( models . Model ) :
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
author = models . OneToOneField ( Author , primary_key = True )
2007-01-27 21:42:51 +08:00
date_of_birth = models . DateField ( )
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
def __unicode__ ( self ) :
return u " Profile of %s " % self . author
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
2007-09-15 13:32:29 +08:00
class Actor ( models . Model ) :
name = models . CharField ( max_length = 20 , primary_key = True )
class Meta :
ordering = ( ' name ' , )
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
2007-09-15 13:32:29 +08:00
def __unicode__ ( self ) :
return self . name
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
2007-09-15 13:32:29 +08:00
class Movie ( models . Model ) :
actor = models . ForeignKey ( Actor )
title = models . CharField ( max_length = 50 )
2009-02-12 04:13:17 +08:00
price = models . DecimalField ( max_digits = 6 , decimal_places = 2 , default = Decimal ( ' 0.00 ' ) )
2007-09-15 13:32:29 +08:00
class Meta :
ordering = ( ' title ' , )
def __unicode__ ( self ) :
return self . title
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
2007-09-22 21:21:54 +08:00
class Score ( models . Model ) :
score = models . FloatField ( )
2007-01-27 21:42:51 +08:00
2006-08-27 21:59:47 +08:00
__test__ = { ' API_TESTS ' : """
2006-06-29 00:00:37 +08:00
# Create some data:
>> > from datetime import datetime
>> > sports = Category ( name = " Sports " )
>> > music = Category ( name = " Music " )
>> > op_ed = Category ( name = " Op-Ed " )
>> > sports . save ( ) ; music . save ( ) ; op_ed . save ( )
>> > joe = Author ( name = " Joe " )
>> > jane = Author ( name = " Jane " )
>> > joe . save ( ) ; jane . save ( )
>> > a1 = Article (
. . . author = jane ,
. . . headline = " Poker has no place on ESPN " ,
. . . pub_date = datetime ( 2006 , 6 , 16 , 11 , 00 ) )
>> > a2 = Article (
. . . author = joe ,
. . . headline = " Time to reform copyright " ,
2007-09-22 21:21:54 +08:00
. . . pub_date = datetime ( 2006 , 6 , 16 , 13 , 00 , 11 , 345 ) )
2006-06-29 00:00:37 +08:00
>> > a1 . save ( ) ; a2 . save ( )
>> > a1 . categories = [ sports , op_ed ]
>> > a2 . categories = [ music , op_ed ]
# Serialize a queryset to XML
>> > from django . core import serializers
>> > xml = serializers . serialize ( " xml " , Article . objects . all ( ) )
# The output is valid XML
>> > from xml . dom import minidom
>> > dom = minidom . parseString ( xml )
# Deserializing has a similar interface, except that special DeserializedObject
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
# instances are returned. This is because data might have changed in the
2006-06-29 00:00:37 +08:00
# database since the data was serialized (we'll simulate that below).
>> > for obj in serializers . deserialize ( " xml " , xml ) :
. . . print obj
< DeserializedObject : Poker has no place on ESPN >
< DeserializedObject : Time to reform copyright >
# Deserializing data with different field values doesn't change anything in the
# database until we call save():
>> > xml = xml . replace ( " Poker has no place on ESPN " , " Poker has no place on television " )
>> > objs = list ( serializers . deserialize ( " xml " , xml ) )
# Even those I deserialized, the database hasn't been touched
>> > Article . objects . all ( )
[ < Article : Poker has no place on ESPN > , < Article : Time to reform copyright > ]
# But when I save, the data changes as you might except.
>> > objs [ 0 ] . save ( )
>> > Article . objects . all ( )
[ < Article : Poker has no place on television > , < Article : Time to reform copyright > ]
2006-06-30 00:42:49 +08:00
# Django also ships with a built-in JSON serializers
>> > json = serializers . serialize ( " json " , Category . objects . filter ( pk = 2 ) )
>> > json
2007-09-15 13:32:29 +08:00
' [ { " pk " : 2, " model " : " serializers.category " , " fields " : { " name " : " Music " }}] '
2006-06-30 00:42:49 +08:00
# You can easily create new objects by deserializing data with an empty PK
# (It's easier to demo this with JSON...)
>> > new_author_json = ' [ { " pk " : null, " model " : " serializers.author " , " fields " : { " name " : " Bill " }}] '
>> > for obj in serializers . deserialize ( " json " , new_author_json ) :
. . . obj . save ( )
>> > Author . objects . all ( )
[ < Author : Bill > , < Author : Jane > , < Author : Joe > ]
# All the serializers work the same
>> > json = serializers . serialize ( " json " , Article . objects . all ( ) )
>> > for obj in serializers . deserialize ( " json " , json ) :
. . . print obj
< DeserializedObject : Poker has no place on television >
< DeserializedObject : Time to reform copyright >
>> > json = json . replace ( " Poker has no place on television " , " Just kidding; I love TV poker " )
>> > for obj in serializers . deserialize ( " json " , json ) :
. . . obj . save ( )
>> > Article . objects . all ( )
[ < Article : Just kidding ; I love TV poker > , < Article : Time to reform copyright > ]
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
# If you use your own primary key field (such as a OneToOneField),
2007-01-27 21:42:51 +08:00
# it doesn't appear in the serialized field list - it replaces the
# pk identifier.
>> > profile = AuthorProfile ( author = joe , date_of_birth = datetime ( 1970 , 1 , 1 ) )
>> > profile . save ( )
>> > json = serializers . serialize ( " json " , AuthorProfile . objects . all ( ) )
>> > json
2007-09-15 13:32:29 +08:00
' [ { " pk " : 1, " model " : " serializers.authorprofile " , " fields " : { " date_of_birth " : " 1970-01-01 " }}] '
2007-01-27 21:42:51 +08:00
>> > for obj in serializers . deserialize ( " json " , json ) :
. . . print obj
< DeserializedObject : Profile of Joe >
2007-02-27 01:33:27 +08:00
# Objects ids can be referenced before they are defined in the serialization data
# However, the deserialization process will need to be contained within a transaction
2007-09-15 13:32:29 +08:00
>> > json = ' [ { " pk " : 3, " model " : " serializers.article " , " fields " : { " headline " : " Forward references pose no problem " , " pub_date " : " 2006-06-16 15:00:00 " , " categories " : [4, 1], " author " : 4}}, { " pk " : 4, " model " : " serializers.category " , " fields " : { " name " : " Reference " }}, { " pk " : 4, " model " : " serializers.author " , " fields " : { " name " : " Agnes " }}] '
2007-02-27 01:33:27 +08:00
>> > from django . db import transaction
>> > transaction . enter_transaction_management ( )
>> > transaction . managed ( True )
>> > for obj in serializers . deserialize ( " json " , json ) :
. . . obj . save ( )
>> > transaction . commit ( )
>> > transaction . leave_transaction_management ( )
>> > article = Article . objects . get ( pk = 3 )
>> > article
< Article : Forward references pose no problem >
>> > article . categories . all ( )
[ < Category : Reference > , < Category : Sports > ]
>> > article . author
< Author : Agnes >
2007-06-01 21:39:08 +08:00
# Serializer output can be restricted to a subset of fields
>> > print serializers . serialize ( " json " , Article . objects . all ( ) , fields = ( ' headline ' , ' pub_date ' ) )
2007-09-22 21:21:54 +08:00
[ { " pk " : 1 , " model " : " serializers.article " , " fields " : { " headline " : " Just kidding; I love TV poker " , " pub_date " : " 2006-06-16 11:00:00 " } } , { " pk " : 2 , " model " : " serializers.article " , " fields " : { " headline " : " Time to reform copyright " , " pub_date " : " 2006-06-16 13:00:11 " } } , { " pk " : 3 , " model " : " serializers.article " , " fields " : { " headline " : " Forward references pose no problem " , " pub_date " : " 2006-06-16 15:00:00 " } } ]
2007-09-15 13:32:29 +08:00
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
# Every string is serialized as a unicode object, also primary key
2007-09-15 13:32:29 +08:00
# which is 'varchar'
>> > ac = Actor ( name = " Zażółć " )
>> > mv = Movie ( title = " Gęślą jaźń " , actor = ac )
>> > ac . save ( ) ; mv . save ( )
# Let's serialize our movie
>> > print serializers . serialize ( " json " , [ mv ] )
2009-02-12 04:13:17 +08:00
[ { " pk " : 1 , " model " : " serializers.movie " , " fields " : { " price " : " 0.00 " , " actor " : " Za \u017c \u00f3 \u0142 \u0107 " , " title " : " G \u0119 \u015b l \u0105 ja \u017a \u0144 " } } ]
2007-09-15 13:32:29 +08:00
# Deserialization of movie
>> > list ( serializers . deserialize ( ' json ' , serializers . serialize ( ' json ' , [ mv ] ) ) ) [ 0 ] . object . title
u ' G \u0119 \u015b l \u0105 ja \u017a \u0144 '
# None is null after serialization to json
# Primary key is None in case of not saved model
>> > mv2 = Movie ( title = " Movie 2 " , actor = ac )
>> > print serializers . serialize ( " json " , [ mv2 ] )
2009-02-12 04:13:17 +08:00
[ { " pk " : null , " model " : " serializers.movie " , " fields " : { " price " : " 0.00 " , " actor " : " Za \u017c \u00f3 \u0142 \u0107 " , " title " : " Movie 2 " } } ]
2007-09-15 13:32:29 +08:00
# Deserialization of null returns None for pk
>> > print list ( serializers . deserialize ( ' json ' , serializers . serialize ( ' json ' , [ mv2 ] ) ) ) [ 0 ] . object . id
None
2007-06-01 21:39:08 +08:00
2007-09-22 21:21:54 +08:00
# Serialization and deserialization of floats:
>> > sc = Score ( score = 3.4 )
>> > print serializers . serialize ( " json " , [ sc ] )
[ { " pk " : null , " model " : " serializers.score " , " fields " : { " score " : 3.4 } } ]
>> > print list ( serializers . deserialize ( ' json ' , serializers . serialize ( ' json ' , [ sc ] ) ) ) [ 0 ] . object . score
3.4
2006-08-27 21:59:47 +08:00
""" }
2007-12-05 04:31:34 +08:00
try :
import yaml
__test__ [ ' YAML ' ] = """
# Create some data:
>> > articles = Article . objects . all ( ) . order_by ( " id " ) [ : 2 ]
>> > from django . core import serializers
# test if serial
>> > serialized = serializers . serialize ( " yaml " , articles )
>> > print serialized
- fields :
author : 2
categories : [ 3 , 1 ]
headline : Just kidding ; I love TV poker
pub_date : 2006 - 06 - 16 11 : 00 : 00
model : serializers . article
pk : 1
- fields :
author : 1
categories : [ 2 , 3 ]
headline : Time to reform copyright
pub_date : 2006 - 06 - 16 13 : 00 : 11
model : serializers . article
pk : 2
< BLANKLINE >
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
>> > obs = list ( serializers . deserialize ( " yaml " , serialized ) )
>> > for i in obs :
2007-12-05 04:31:34 +08:00
. . . print i
< DeserializedObject : Just kidding ; I love TV poker >
< DeserializedObject : Time to reform copyright >
"""
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing
code. Also adds a couple of new features.
Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-04-27 10:50:16 +08:00
except ImportError :
pass