2009-12-22 15:18:51 +00:00
from django . db import models , DEFAULT_DB_ALIAS
2007-07-20 12:07:58 +00:00
from django . contrib . auth . models import User
2007-09-15 00:08:08 +00:00
from django . conf import settings
2008-02-22 12:50:10 +00:00
import os
2007-04-06 02:25:58 +00:00
class Animal ( models . Model ) :
2007-08-05 05:14:46 +00:00
name = models . CharField ( max_length = 150 )
latin_name = models . CharField ( max_length = 150 )
2008-08-24 08:12:13 +00:00
count = models . IntegerField ( )
2009-01-03 04:43:58 +00:00
weight = models . FloatField ( )
2008-11-06 11:19:13 +00:00
2009-06-09 13:14:40 +00:00
# use a non-default name for the default manager
specimens = models . Manager ( )
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 12:11:04 +00:00
def __unicode__ ( self ) :
2009-12-14 12:39:20 +00:00
return self . name
2007-04-06 02:25:58 +00:00
2008-08-24 08:12:13 +00:00
def animal_pre_save_check ( signal , sender , instance , * * kwargs ) :
" A signal that is used to check the type of data loaded from fixtures "
print ' Count = %s ( %s ) ' % ( instance . count , type ( instance . count ) )
2009-01-03 04:43:58 +00:00
print ' Weight = %s ( %s ) ' % ( instance . weight , type ( instance . weight ) )
2008-08-24 08:12:13 +00:00
2007-04-17 11:11:26 +00:00
class Plant ( models . Model ) :
2007-08-05 05:14:46 +00:00
name = models . CharField ( max_length = 150 )
2007-04-17 11:11:26 +00:00
class Meta :
# For testing when upper case letter in app name; regression for #4057
db_table = " Fixtures_regress_plant "
2007-07-20 12:07:58 +00:00
class Stuff ( models . Model ) :
2007-08-05 05:14:46 +00:00
name = models . CharField ( max_length = 20 , null = True )
2007-07-20 12:07:58 +00:00
owner = models . ForeignKey ( User , null = True )
2008-06-30 00:38:14 +00:00
2007-07-20 12:07:58 +00:00
def __unicode__ ( self ) :
2007-09-15 00:08:08 +00:00
# Oracle doesn't distinguish between None and the empty string.
# This hack makes the test case pass using Oracle.
name = self . name
2009-12-22 15:18:51 +00:00
if ( settings . DATABASES [ DEFAULT_DB_ALIAS ] [ ' ENGINE ' ] == ' django.db.backends.oracle '
and name == u ' ' ) :
2007-09-15 00:08:08 +00:00
name = None
return unicode ( name ) + u ' is owned by ' + unicode ( self . owner )
2007-07-20 12:07:58 +00:00
2008-02-22 12:50:10 +00:00
class Absolute ( models . Model ) :
name = models . CharField ( max_length = 40 )
load_count = 0
def __init__ ( self , * args , * * kwargs ) :
super ( Absolute , self ) . __init__ ( * args , * * kwargs )
Absolute . load_count + = 1
2008-06-30 00:38:14 +00:00
class Parent ( models . Model ) :
name = models . CharField ( max_length = 10 )
2010-03-18 15:22:15 +00:00
class Meta :
ordering = ( ' id ' , )
2008-06-30 00:38:14 +00:00
class Child ( Parent ) :
data = models . CharField ( max_length = 10 )
2009-07-27 14:32:30 +00:00
# Models to regression test #7572
2008-06-30 12:18:29 +00:00
class Channel ( models . Model ) :
name = models . CharField ( max_length = 255 )
class Article ( models . Model ) :
title = models . CharField ( max_length = 255 )
channels = models . ManyToManyField ( Channel )
2008-11-06 11:19:13 +00:00
2008-06-30 12:18:29 +00:00
class Meta :
ordering = ( ' id ' , )
2008-02-22 12:50:10 +00:00
2009-07-27 14:32:30 +00:00
# Models to regression test #11428
class Widget ( models . Model ) :
name = models . CharField ( max_length = 255 )
2009-12-14 12:39:20 +00:00
class Meta :
ordering = ( ' name ' , )
def __unicode__ ( self ) :
return self . name
2009-07-27 14:32:30 +00:00
class WidgetProxy ( Widget ) :
class Meta :
proxy = True
2009-12-14 12:39:20 +00:00
# Check for forward references in FKs and M2Ms with natural keys
class TestManager ( models . Manager ) :
def get_by_natural_key ( self , key ) :
return self . get ( name = key )
class Store ( models . Model ) :
objects = TestManager ( )
name = models . CharField ( max_length = 255 )
class Meta :
ordering = ( ' name ' , )
def __unicode__ ( self ) :
return self . name
def natural_key ( self ) :
return ( self . name , )
class Person ( models . Model ) :
objects = TestManager ( )
name = models . CharField ( max_length = 255 )
class Meta :
ordering = ( ' name ' , )
def __unicode__ ( self ) :
return self . name
# Person doesn't actually have a dependency on store, but we need to define
# one to test the behaviour of the dependency resolution algorithm.
def natural_key ( self ) :
return ( self . name , )
natural_key . dependencies = [ ' fixtures_regress.store ' ]
class Book ( models . Model ) :
name = models . CharField ( max_length = 255 )
author = models . ForeignKey ( Person )
stores = models . ManyToManyField ( Store )
class Meta :
ordering = ( ' name ' , )
def __unicode__ ( self ) :
return u ' %s by %s (available at %s ) ' % (
self . name ,
self . author . name ,
' , ' . join ( s . name for s in self . stores . all ( ) )
)
2010-03-18 15:22:15 +00:00
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 ( ) )
)
2009-12-17 21:54:37 +00:00
# ome models with pathological circular dependencies
class Circle1 ( models . Model ) :
name = models . CharField ( max_length = 255 )
def natural_key ( self ) :
return self . name
natural_key . dependencies = [ ' fixtures_regress.circle2 ' ]
class Circle2 ( models . Model ) :
name = models . CharField ( max_length = 255 )
def natural_key ( self ) :
return self . name
natural_key . dependencies = [ ' fixtures_regress.circle1 ' ]
class Circle3 ( models . Model ) :
name = models . CharField ( max_length = 255 )
def natural_key ( self ) :
return self . name
natural_key . dependencies = [ ' fixtures_regress.circle3 ' ]
class Circle4 ( models . Model ) :
name = models . CharField ( max_length = 255 )
def natural_key ( self ) :
return self . name
natural_key . dependencies = [ ' fixtures_regress.circle5 ' ]
class Circle5 ( models . Model ) :
name = models . CharField ( max_length = 255 )
def natural_key ( self ) :
return self . name
natural_key . dependencies = [ ' fixtures_regress.circle6 ' ]
class Circle6 ( models . Model ) :
name = models . CharField ( max_length = 255 )
def natural_key ( self ) :
return self . name
natural_key . dependencies = [ ' fixtures_regress.circle4 ' ]
class ExternalDependency ( models . Model ) :
name = models . CharField ( max_length = 255 )
def natural_key ( self ) :
return self . name
natural_key . dependencies = [ ' fixtures_regress.book ' ]
2007-04-06 02:25:58 +00:00
__test__ = { ' API_TESTS ' : """
>> > from django . core import management
# Load a fixture that uses PK=1
2007-08-16 06:06:55 +00:00
>> > management . call_command ( ' loaddata ' , ' sequence ' , verbosity = 0 )
2008-06-30 00:38:14 +00:00
2007-04-06 02:25:58 +00:00
# Create a new animal. Without a sequence reset, this new object
# will take a PK of 1 (on Postgres), and the save will fail.
# This is a regression test for ticket #3790.
2010-01-09 19:17:35 +00:00
>> > animal = Animal ( name = ' Platypus ' , latin_name = ' Ornithorhynchus anatinus ' , count = 2 , weight = 2.2 )
2007-04-06 02:25:58 +00:00
>> > animal . save ( )
2007-07-20 12:07:58 +00:00
###############################################
# Regression test for ticket #4558 -- pretty printing of XML fixtures
# doesn't affect parsing of None values.
# Load a pretty-printed XML fixture with Nulls.
2007-08-16 06:06:55 +00:00
>> > management . call_command ( ' loaddata ' , ' pretty.xml ' , verbosity = 0 )
2007-07-20 12:07:58 +00:00
>> > Stuff . objects . all ( )
[ < Stuff : None is owned by None > ]
2008-02-22 12:50:10 +00:00
###############################################
2008-06-30 00:38:14 +00:00
# Regression test for ticket #6436 --
2008-02-22 12:50:10 +00:00
# os.path.join will throw away the initial parts of a path if it encounters
2008-06-30 00:38:14 +00:00
# an absolute path. This means that if a fixture is specified as an absolute path,
2008-02-22 12:50:10 +00:00
# we need to make sure we don't discover the absolute path in every fixture directory.
>> > load_absolute_path = os . path . join ( os . path . dirname ( __file__ ) , ' fixtures ' , ' absolute.json ' )
>> > management . call_command ( ' loaddata ' , load_absolute_path , verbosity = 0 )
>> > Absolute . load_count
1
2008-06-08 08:21:18 +00:00
###############################################
# Test for ticket #4371 -- fixture loading fails silently in testcases
# Validate that error conditions are caught correctly
# redirect stderr for the next few tests...
>> > import sys
>> > savestderr = sys . stderr
>> > sys . stderr = sys . stdout
# Loading data of an unknown format should fail
>> > management . call_command ( ' loaddata ' , ' bad_fixture1.unkn ' , verbosity = 0 )
Problem installing fixture ' bad_fixture1 ' : unkn is not a known serialization format .
# Loading a fixture file with invalid data using explicit filename
>> > management . call_command ( ' loaddata ' , ' bad_fixture2.xml ' , verbosity = 0 )
No fixture data found for ' bad_fixture2 ' . ( File format may be invalid . )
# Loading a fixture file with invalid data without file extension
>> > management . call_command ( ' loaddata ' , ' bad_fixture2 ' , verbosity = 0 )
No fixture data found for ' bad_fixture2 ' . ( File format may be invalid . )
2008-11-06 11:19:13 +00:00
# Loading a fixture file with no data returns an error
>> > management . call_command ( ' loaddata ' , ' empty ' , verbosity = 0 )
No fixture data found for ' empty ' . ( File format may be invalid . )
# If any of the fixtures contain an error, loading is aborted
# (Regression for #9011 - error message is correct)
>> > management . call_command ( ' loaddata ' , ' bad_fixture2 ' , ' animal ' , verbosity = 0 )
No fixture data found for ' bad_fixture2 ' . ( File format may be invalid . )
2008-06-08 08:21:18 +00:00
>> > sys . stderr = savestderr
2008-06-30 00:38:14 +00:00
###############################################
# Test for ticket #7565 -- PostgreSQL sequence resetting checks shouldn't
# ascend to parent models when inheritance is used (since they are treated
# individually).
>> > management . call_command ( ' loaddata ' , ' model-inheritance.json ' , verbosity = 0 )
2010-03-18 15:22:15 +00:00
###############################################
# 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 ] >
2008-06-30 12:18:29 +00:00
###############################################
2008-11-06 11:19:13 +00:00
# Test for ticket #7572 -- MySQL has a problem if the same connection is
2008-06-30 12:18:29 +00:00
# used to create tables, load data, and then query over that data.
# To compensate, we close the connection after running loaddata.
# This ensures that a new connection is opened when test queries are issued.
>> > management . call_command ( ' loaddata ' , ' big-fixture.json ' , verbosity = 0 )
>> > articles = Article . objects . exclude ( id = 9 )
>> > articles . values_list ( ' id ' , flat = True )
[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]
# Just for good measure, run the same query again. Under the influence of
# ticket #7572, this will give a different result to the previous call.
>> > articles . values_list ( ' id ' , flat = True )
[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]
2008-08-24 08:12:13 +00:00
###############################################
2009-01-03 04:43:58 +00:00
# Test for tickets #8298, #9942 - Field values should be coerced into the
# correct type by the deserializer, not as part of the database write.
2008-08-24 08:12:13 +00:00
>> > models . signals . pre_save . connect ( animal_pre_save_check )
>> > management . call_command ( ' loaddata ' , ' animal.xml ' , verbosity = 0 )
Count = 42 ( < type ' int ' > )
2009-01-03 04:43:58 +00:00
Weight = 1.2 ( < type ' float ' > )
2008-08-24 08:12:13 +00:00
>> > models . signals . pre_save . disconnect ( animal_pre_save_check )
2009-06-09 13:14:40 +00:00
###############################################
# Regression for #11286 -- Ensure that dumpdata honors the default manager
# Dump the current contents of the database as a JSON fixture
>> > management . call_command ( ' dumpdata ' , ' fixtures_regress.animal ' , format = ' json ' )
2010-01-09 19:17:35 +00:00
[ { " 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 " } } ]
2009-06-09 13:14:40 +00:00
2009-07-27 14:32:30 +00:00
###############################################
2010-03-18 15:22:15 +00:00
# Regression for #11428 - Proxy models aren't included when you dumpdata
2009-07-27 14:32:30 +00:00
# Flush out the database first
>> > management . call_command ( ' reset ' , ' fixtures_regress ' , interactive = False , verbosity = 0 )
# Create an instance of the concrete class
>> > Widget ( name = ' grommet ' ) . save ( )
# Dump data for the entire app. The proxy class shouldn't be included
2009-12-17 21:54:37 +00:00
>> > management . call_command ( ' dumpdata ' , ' fixtures_regress.widget ' , ' fixtures_regress.widgetproxy ' , format = ' json ' )
2009-07-27 14:32:30 +00:00
[ { " pk " : 1 , " model " : " fixtures_regress.widget " , " fields " : { " name " : " grommet " } } ]
2009-12-14 12:39:20 +00:00
###############################################
# Check that natural key requirements are taken into account
# when serializing models
>> > management . call_command ( ' loaddata ' , ' forward_ref_lookup.json ' , verbosity = 0 )
>> > management . call_command ( ' dumpdata ' , ' fixtures_regress.book ' , ' fixtures_regress.person ' , ' fixtures_regress.store ' , verbosity = 0 , use_natural_keys = True )
[ { " pk " : 2 , " model " : " fixtures_regress.store " , " fields " : { " name " : " Amazon " } } , { " pk " : 3 , " model " : " fixtures_regress.store " , " fields " : { " name " : " Borders " } } , { " pk " : 4 , " model " : " fixtures_regress.person " , " fields " : { " name " : " Neal Stephenson " } } , { " pk " : 1 , " model " : " fixtures_regress.book " , " fields " : { " stores " : [ [ " Amazon " ] , [ " Borders " ] ] , " name " : " Cryptonomicon " , " author " : [ " Neal Stephenson " ] } } ]
# Now lets check the dependency sorting explicitly
# It doesn't matter what order you mention the models
# Store *must* be serialized before then Person, and both
# must be serialized before Book.
>> > from django . core . management . commands . dumpdata import sort_dependencies
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Book , Person , Store ] ) ] )
[ < class ' regressiontests . fixtures_regress . models . Store ' >, <class ' regressiontests . fixtures_regress . models . Person ' >, <class ' regressiontests . fixtures_regress . models . Book ' >]
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Book , Store , Person ] ) ] )
[ < class ' regressiontests . fixtures_regress . models . Store ' >, <class ' regressiontests . fixtures_regress . models . Person ' >, <class ' regressiontests . fixtures_regress . models . Book ' >]
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Store , Book , Person ] ) ] )
[ < class ' regressiontests . fixtures_regress . models . Store ' >, <class ' regressiontests . fixtures_regress . models . Person ' >, <class ' regressiontests . fixtures_regress . models . Book ' >]
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Store , Person , Book ] ) ] )
[ < class ' regressiontests . fixtures_regress . models . Store ' >, <class ' regressiontests . fixtures_regress . models . Person ' >, <class ' regressiontests . fixtures_regress . models . Book ' >]
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Person , Book , Store ] ) ] )
[ < class ' regressiontests . fixtures_regress . models . Store ' >, <class ' regressiontests . fixtures_regress . models . Person ' >, <class ' regressiontests . fixtures_regress . models . Book ' >]
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Person , Store , Book ] ) ] )
[ < class ' regressiontests . fixtures_regress . models . Store ' >, <class ' regressiontests . fixtures_regress . models . Person ' >, <class ' regressiontests . fixtures_regress . models . Book ' >]
# A dangling dependency - assume the user knows what they are doing.
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Person , Circle1 , Store , Book ] ) ] )
[ < class ' regressiontests . fixtures_regress . models . Circle1 ' >, <class ' regressiontests . fixtures_regress . models . Store ' >, <class ' regressiontests . fixtures_regress . models . Person ' >, <class ' regressiontests . fixtures_regress . models . Book ' >]
# A tight circular dependency
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Person , Circle2 , Circle1 , Store , Book ] ) ] )
Traceback ( most recent call last ) :
. . .
CommandError : Can ' t resolve dependencies for fixtures_regress.Circle1, fixtures_regress.Circle2 in serialized app list.
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Circle1 , Book , Circle2 ] ) ] )
Traceback ( most recent call last ) :
. . .
CommandError : Can ' t resolve dependencies for fixtures_regress.Circle1, fixtures_regress.Circle2 in serialized app list.
# A self referential dependency
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Book , Circle3 ] ) ] )
Traceback ( most recent call last ) :
. . .
CommandError : Can ' t resolve dependencies for fixtures_regress.Circle3 in serialized app list.
# A long circular dependency
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Person , Circle2 , Circle1 , Circle3 , Store , Book ] ) ] )
Traceback ( most recent call last ) :
. . .
CommandError : Can ' t resolve dependencies for fixtures_regress.Circle1, fixtures_regress.Circle2, fixtures_regress.Circle3 in serialized app list.
# A dependency on a normal, non-natural-key model
>> > sort_dependencies ( [ ( ' fixtures_regress ' , [ Person , ExternalDependency , Book ] ) ] )
[ < class ' regressiontests . fixtures_regress . models . Person ' >, <class ' regressiontests . fixtures_regress . models . Book ' >, <class ' regressiontests . fixtures_regress . models . ExternalDependency ' >]
###############################################
# Check that normal primary keys still work
# on a model with natural key capabilities
>> > management . call_command ( ' loaddata ' , ' non_natural_1.json ' , verbosity = 0 )
>> > management . call_command ( ' loaddata ' , ' non_natural_2.xml ' , verbosity = 0 )
>> > Book . objects . all ( )
[ < Book : Cryptonomicon by Neal Stephenson ( available at Amazon , Borders ) > , < Book : Ender ' s Game by Orson Scott Card (available at Collins Bookstore)>, <Book: Permutation City by Greg Egan (available at Angus and Robertson)>]
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 12:11:04 +00:00
""" }
2009-12-14 12:39:20 +00:00