2006-05-02 09:31:56 +08:00
"""
4. Many - to - one relationships
To define a many - to - one relationship , use ` ` ForeignKey ( ) ` ` .
"""
from django . db import models
class Reporter ( models . Model ) :
2007-08-05 13:14:46 +08:00
first_name = models . CharField ( max_length = 30 )
last_name = models . CharField ( max_length = 30 )
2006-05-02 09:31:56 +08:00
email = models . EmailField ( )
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 " %s %s " % ( self . first_name , self . last_name )
2006-05-02 09:31:56 +08:00
class Article ( models . Model ) :
2007-08-05 13:14:46 +08:00
headline = models . CharField ( max_length = 100 )
2006-05-02 09:31:56 +08:00
pub_date = models . DateField ( )
reporter = models . ForeignKey ( Reporter )
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-05-02 09:31:56 +08:00
return self . headline
class Meta :
ordering = ( ' headline ' , )
2006-08-27 21:59:47 +08:00
__test__ = { ' API_TESTS ' : """
2006-05-02 09:31:56 +08:00
# Create a few Reporters.
>> > r = Reporter ( first_name = ' John ' , last_name = ' Smith ' , email = ' john@example.com ' )
>> > r . save ( )
>> > r2 = Reporter ( first_name = ' Paul ' , last_name = ' Jones ' , email = ' paul@example.com ' )
>> > r2 . save ( )
# Create an Article.
>> > from datetime import datetime
>> > a = Article ( id = None , headline = " This is a test " , pub_date = datetime ( 2005 , 7 , 27 ) , reporter = r )
>> > a . save ( )
>> > a . reporter . id
1
>> > a . reporter
2006-06-04 08:23:51 +08:00
< Reporter : John Smith >
2006-05-02 09:31:56 +08:00
# Article objects have access to their related Reporter objects.
>> > r = a . reporter
>> > r . first_name , r . last_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
( u ' John ' , u ' Smith ' )
2006-05-02 09:31:56 +08:00
# Create an Article via the Reporter object.
>> > new_article = r . article_set . create ( headline = " John ' s second story " , pub_date = datetime ( 2005 , 7 , 29 ) )
>> > new_article
2006-06-04 08:23:51 +08:00
< Article : John ' s second story>
2006-05-02 09:31:56 +08:00
>> > new_article . reporter . id
1
# Create a new article, and add it to the article set.
>> > new_article2 = Article ( headline = " Paul ' s story " , pub_date = datetime ( 2006 , 1 , 17 ) )
>> > r . article_set . add ( new_article2 )
>> > new_article2 . reporter . id
1
>> > r . article_set . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: Paul ' s story > , < Article : This is a test > ]
2006-05-02 09:31:56 +08:00
# Add the same article to a different article set - check that it moves.
>> > r2 . article_set . add ( new_article2 )
>> > new_article2 . reporter . id
2
>> > r . article_set . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
>> > r2 . article_set . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : Paul ' s story>]
2006-05-02 09:31:56 +08:00
# Assign the article to the reporter directly using the descriptor
>> > new_article2 . reporter = r
>> > new_article2 . save ( )
>> > new_article2 . reporter
2006-06-04 08:23:51 +08:00
< Reporter : John Smith >
2006-05-02 09:31:56 +08:00
>> > new_article2 . reporter . id
1
>> > r . article_set . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: Paul ' s story > , < Article : This is a test > ]
2006-05-02 09:31:56 +08:00
>> > r2 . article_set . all ( )
[ ]
# Set the article back again using set descriptor.
>> > r2 . article_set = [ new_article , new_article2 ]
>> > r . article_set . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : This is a test > ]
2006-05-02 09:31:56 +08:00
>> > r2 . article_set . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: Paul ' s story > ]
2006-05-02 09:31:56 +08:00
2006-06-04 08:23:51 +08:00
# Funny case - assignment notation can only go so far; because the
2006-05-02 09:31:56 +08:00
# ForeignKey cannot be null, existing members of the set must remain
>> > r . article_set = [ new_article ]
>> > r . article_set . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
>> > r2 . article_set . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : Paul ' s story>]
2006-05-02 09:31:56 +08:00
# Reporter cannot be null - there should not be a clear or remove method
>> > hasattr ( r2 . article_set , ' remove ' )
False
>> > hasattr ( r2 . article_set , ' clear ' )
False
# Reporter objects have access to their related Article objects.
>> > r . article_set . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
>> > r . article_set . filter ( headline__startswith = ' This ' )
2006-06-04 08:23:51 +08:00
[ < Article : This is a test > ]
2006-05-02 09:31:56 +08:00
>> > r . article_set . count ( )
2
>> > r2 . article_set . count ( )
1
# Get articles by id
>> > Article . objects . filter ( id__exact = 1 )
2006-06-04 08:23:51 +08:00
[ < Article : This is a test > ]
2006-05-02 09:31:56 +08:00
>> > Article . objects . filter ( pk = 1 )
2006-06-04 08:23:51 +08:00
[ < Article : This is a test > ]
2006-05-02 09:31:56 +08:00
# Query on an article property
>> > Article . objects . filter ( headline__startswith = ' This ' )
2006-06-04 08:23:51 +08:00
[ < Article : This is a test > ]
2006-05-02 09:31:56 +08:00
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want. There's no limit.
# Find all Articles for any Reporter whose first name is "John".
>> > Article . objects . filter ( reporter__first_name__exact = ' John ' )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
2006-07-01 11:14:33 +08:00
# Check that implied __exact also works
>> > Article . objects . filter ( reporter__first_name = ' John ' )
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
# Query twice over the related field.
>> > Article . objects . filter ( reporter__first_name__exact = ' John ' , reporter__last_name__exact = ' Smith ' )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
# The underlying query only makes one join when a related table is referenced twice.
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
>> > queryset = Article . objects . filter ( reporter__first_name__exact = ' John ' , reporter__last_name__exact = ' Smith ' )
>> > sql = queryset . query . as_sql ( ) [ 0 ]
2006-05-02 09:31:56 +08:00
>> > sql . count ( ' INNER JOIN ' )
1
# The automatically joined table has a predictable 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
>> > Article . objects . filter ( reporter__first_name__exact = ' John ' ) . extra ( where = [ " many_to_one_reporter.last_name= ' Smith ' " ] )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +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
# And should work fine with the unicode that comes out of
2008-07-19 09:22:26 +08:00
# forms.Form.cleaned_data
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
>> > Article . objects . filter ( reporter__first_name__exact = ' John ' ) . extra ( where = [ " many_to_one_reporter.last_name= ' %s ' " % u ' Smith ' ] )
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
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
# Find all Articles for the Reporter whose ID is 1.
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
# Use direct ID check, pk check, and object comparison
2006-05-02 09:31:56 +08:00
>> > Article . objects . filter ( reporter__id__exact = 1 )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
>> > Article . objects . filter ( reporter__pk = 1 )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: This is a test>]
2006-07-01 09:14:41 +08:00
>> > Article . objects . filter ( reporter = 1 )
[ < Article : John ' s second story>, <Article: This is a test>]
>> > Article . objects . filter ( reporter = r )
[ < Article : John ' s second story>, <Article: This is a test>]
>> > Article . objects . filter ( reporter__in = [ 1 , 2 ] ) . distinct ( )
[ < Article : John ' s second story>, <Article: Paul ' s story > , < Article : This is a test > ]
>> > Article . objects . filter ( reporter__in = [ r , r2 ] ) . distinct ( )
[ < Article : John ' s second story>, <Article: Paul ' s story > , < Article : This is a test > ]
2006-05-02 09:31:56 +08:00
2008-06-12 21:19:37 +08:00
# You can also use a queryset instead of a literal list of instances.
# The queryset must be reduced to a list of values using values(),
# then converted into a query
>> > Article . objects . filter ( reporter__in = Reporter . objects . filter ( first_name = ' John ' ) . values ( ' pk ' ) . query ) . distinct ( )
[ < Article : John ' s second story>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
# You need two underscores between "reporter" and "id" -- not one.
>> > Article . objects . filter ( reporter_id__exact = 1 )
Traceback ( most recent call last ) :
. . .
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
FieldError : Cannot resolve keyword ' reporter_id ' into field . Choices are : headline , id , pub_date , reporter
2006-05-02 09:31:56 +08:00
# You need to specify a comparison clause
>> > Article . objects . filter ( reporter_id = 1 )
Traceback ( most recent call last ) :
. . .
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
FieldError : Cannot resolve keyword ' reporter_id ' into field . Choices are : headline , id , pub_date , reporter
2006-05-02 09:31:56 +08:00
# You can also instantiate an Article by passing
# the Reporter's ID instead of a Reporter object.
>> > a3 = Article ( id = None , headline = " This is a test " , pub_date = datetime ( 2005 , 7 , 27 ) , reporter_id = r . id )
>> > a3 . save ( )
>> > a3 . reporter . id
1
>> > a3 . reporter
2006-06-04 08:23:51 +08:00
< Reporter : John Smith >
2006-05-02 09:31:56 +08:00
# Similarly, the reporter ID can be a string.
>> > a4 = Article ( id = None , headline = " This is a test " , pub_date = datetime ( 2005 , 7 , 27 ) , reporter_id = " 1 " )
>> > a4 . save ( )
>> > a4 . reporter
2006-06-04 08:23:51 +08:00
< Reporter : John Smith >
2006-05-02 09:31:56 +08:00
# Reporters can be queried
>> > Reporter . objects . filter ( id__exact = 1 )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
>> > Reporter . objects . filter ( pk = 1 )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
>> > Reporter . objects . filter ( first_name__startswith = ' John ' )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
# Reporters can query in opposite direction of ForeignKey definition
>> > Reporter . objects . filter ( article__id__exact = 1 )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
>> > Reporter . objects . filter ( article__pk = 1 )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > ]
2006-07-01 09:14:41 +08:00
>> > Reporter . objects . filter ( article = 1 )
[ < Reporter : John Smith > ]
>> > Reporter . objects . filter ( article = a )
[ < Reporter : John Smith > ]
>> > Reporter . objects . filter ( article__in = [ 1 , 4 ] ) . distinct ( )
[ < Reporter : John Smith > ]
>> > Reporter . objects . filter ( article__in = [ 1 , a3 ] ) . distinct ( )
[ < Reporter : John Smith > ]
>> > Reporter . objects . filter ( article__in = [ a , a3 ] ) . distinct ( )
[ < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
>> > Reporter . objects . filter ( article__headline__startswith = ' This ' )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > , < Reporter : John Smith > , < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
>> > Reporter . objects . filter ( article__headline__startswith = ' This ' ) . distinct ( )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
2006-05-15 07:49:29 +08:00
# Counting in the opposite direction works in conjunction with distinct()
>> > Reporter . objects . filter ( article__headline__startswith = ' This ' ) . count ( )
3
>> > Reporter . objects . filter ( article__headline__startswith = ' This ' ) . distinct ( ) . count ( )
1
2006-05-02 09:31:56 +08:00
# Queries can go round in circles.
>> > Reporter . objects . filter ( article__reporter__first_name__startswith = ' John ' )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > , < Reporter : John Smith > , < Reporter : John Smith > , < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
>> > Reporter . objects . filter ( article__reporter__first_name__startswith = ' John ' ) . distinct ( )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > ]
2006-07-01 09:14:41 +08:00
>> > Reporter . objects . filter ( article__reporter__exact = r ) . distinct ( )
[ < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
2008-04-28 08:03:01 +08:00
# Check that implied __exact also works.
2006-07-01 11:14:33 +08:00
>> > Reporter . objects . filter ( article__reporter = r ) . distinct ( )
[ < Reporter : John Smith > ]
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
# It's possible to use values() calls across many-to-one relations. (Note, too, that we clear the ordering here so as not to drag the 'headline' field into the columns being used to determine uniqueness.)
>> > d = { ' reporter__first_name ' : u ' John ' , ' reporter__last_name ' : u ' Smith ' }
>> > list ( Article . objects . filter ( reporter = r ) . distinct ( ) . order_by ( ) . values ( ' reporter__first_name ' , ' reporter__last_name ' ) ) == [ d ]
True
2006-05-02 09:31:56 +08:00
# If you delete a reporter, his articles will be deleted.
>> > Article . objects . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: Paul ' s story > , < Article : This is a test > , < Article : This is a test > , < Article : This is a test > ]
2006-05-02 09:31:56 +08:00
>> > Reporter . objects . order_by ( ' first_name ' )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > , < Reporter : Paul Jones > ]
2006-05-02 09:31:56 +08:00
>> > r2 . delete ( )
>> > Article . objects . all ( )
2006-06-04 08:23:51 +08:00
[ < Article : John ' s second story>, <Article: This is a test>, <Article: This is a test>, <Article: This is a test>]
2006-05-02 09:31:56 +08:00
>> > Reporter . objects . order_by ( ' first_name ' )
2006-06-04 08:23:51 +08:00
[ < Reporter : John Smith > ]
2006-05-02 09:31:56 +08:00
2008-04-28 08:03:01 +08:00
# You can delete using a JOIN in the query.
2006-05-02 09:31:56 +08:00
>> > Reporter . objects . filter ( article__headline__startswith = ' This ' ) . delete ( )
>> > Reporter . objects . all ( )
[ ]
>> > Article . objects . all ( )
[ ]
2008-04-28 08:03:01 +08:00
# Check that Article.objects.select_related().dates() works properly when
# there are multiple Articles with the same date but different foreign-key
# objects (Reporters).
>> > r1 = Reporter . objects . create ( first_name = ' Mike ' , last_name = ' Royko ' , email = ' royko@suntimes.com ' )
>> > r2 = Reporter . objects . create ( first_name = ' John ' , last_name = ' Kass ' , email = ' jkass@tribune.com ' )
>> > a1 = Article . objects . create ( headline = ' First ' , pub_date = datetime ( 1980 , 4 , 23 ) , reporter = r1 )
>> > a2 = Article . objects . create ( headline = ' Second ' , pub_date = datetime ( 1980 , 4 , 23 ) , reporter = r2 )
>> > Article . objects . select_related ( ) . dates ( ' pub_date ' , ' day ' )
[ datetime . datetime ( 1980 , 4 , 23 , 0 , 0 ) ]
>> > Article . objects . select_related ( ) . dates ( ' pub_date ' , ' month ' )
[ datetime . datetime ( 1980 , 4 , 1 , 0 , 0 ) ]
>> > Article . objects . select_related ( ) . dates ( ' pub_date ' , ' year ' )
[ datetime . datetime ( 1980 , 1 , 1 , 0 , 0 ) ]
2006-08-27 21:59:47 +08:00
""" }