save it into the database you have to call save explicitly you can initialize a model instance using positional arguments which should match the field order as defined in the model you can also mix and match position and keyword arguments but be sure not to duplicate field information you can leave off the value for an autofield when creating an object because it ll get filled in automatically when you save as much precision in seconds a1 article headlinearticle 7 pubdatedatetime2005 7 31 12 30 a1 save self assertequal article objects getidexacta1 id pubdate datetime2005 7 31 12 30 a2 article headlinearticle 8 pubdatedatetime2005 7 31 12 30 45 a2 save self assertequal article objects getidexacta2 id pubdate datetime2005 7 31 12 30 45 def testsavinganobjectagaindoesnotcreateanewobjectself a articleheadlineoriginal pubdatedatetime2014 5 16 a save currentid a id a save self assertequala id currentid a headline updated headline a save self assertequala id currentid def testquerysetscheckingformembershipself headlines parrot programs in python second article third article somepubdate datetime2014 5 16 12 1 for headline in headlines articleheadlineheadline pubdatesomepubdate save a articleheadlinesome headline pubdatesomepubdate a save you can use in to test for membership self assertina article objects all but there will often be more efficient ways if that is all you need self asserttruearticle objects filterida id exists def testsaveprimarywithdefaultself an update attempt is skipped when a primary key has default with self assertnumqueries1 primarykeywithdefault save def testsaveprimarywithdbdefaultself an update attempt is skipped when a primary key has dbdefault with self assertnumqueries1 primarykeywithdbdefault save def testsaveparentprimarywithdefaultself an update attempt is skipped when an inherited primary key has default with self assertnumqueries2 childprimarykeywithdefault save class modeltesttestcase def testobjectsattributeisonlyavailableontheclassitselfself with self assertraisesmessage attributeerror manager isn t accessible via article instances getattr article objects self assertfalsehasattrarticle objects self asserttruehasattrarticle objects def testquerysetdeleteremovesallitemsinthatquerysetself headlines an article article one amazing article boring article somepubdate datetime2014 5 16 12 1 for headline in headlines articleheadlineheadline pubdatesomepubdate save self assertquerysetequal article objects orderbyheadline sortedheadlines transformlambda a a headline article objects filterheadlinestartswitha delete self assertequalarticle objects get headline boring article def testnotequalandequaloperatorsbehaveasexpectedoninstancesself somepubdate datetime2014 5 16 12 1 a1 article objects createheadlinefirst pubdatesomepubdate a2 article objects createheadlinesecond pubdatesomepubdate self assertnotequala1 a2 self assertequala1 article objects getidexacta1 id self assertnotequal article objects getidexacta1 id article objects getidexacta2 id def testmicrosecondprecisionself a9 article headlinearticle 9 pubdatedatetime2005 7 31 12 30 45 180 a9 save self assertequal article objects getpka9 pk pubdate datetime2005 7 31 12 30 45 180 def testmanuallyspecifyprimarykeyself you can manually specify the primary key when creating a new object a101 article id101 headlinearticle 101 pubdatedatetime2005 7 31 12 30 45 a101 save a101 article objects getpk101 self assertequala101 headline article 101 def testcreatemethodself you can create saved objects in a single step a10 article objects create headlinearticle 10 pubdatedatetime2005 7 31 12 30 45 self assertequalarticle objects getheadlinearticle 10 a10 def testyearlookupedgecaseself edgecase test a year lookup should retrieve all objects in the given year including jan 1 and dec 31 a11 article objects create headlinearticle 11 pubdatedatetime2008 1 1 a12 article objects create headlinearticle 12 pubdatedatetime2008 12 31 23 59 59 999999 self assertsequenceequal article objects filterpubdateyear2008 a11 a12 def testunicodedataself unicode data works too a article headlineu6797u539f u3081u3050u307f pubdatedatetime2005 7 28 a save self assertequal article objects getpka id headline u6797u539f u3081u3050u307f def testhashfunctionself model instances have a hash function so they can be used in sets or as dictionary keys two models compare as equal if their primary keys are equal a10 article objects create headlinearticle 10 pubdatedatetime2005 7 31 12 30 45 a11 article objects create headlinearticle 11 pubdatedatetime2008 1 1 a12 article objects create headlinearticle 12 pubdatedatetime2008 12 31 23 59 59 999999 s a10 a11 a12 self assertinarticle objects getheadlinearticle 11 s def testextramethodselectargumentwithdashesandvaluesself the select argument to extra supports names with dashes in them as long as you use values article objects bulkcreate article headlinearticle 10 pubdatedatetime2005 7 31 12 30 45 articleheadlinearticle 11 pubdatedatetime2008 1 1 article headlinearticle 12 pubdatedatetime2008 12 31 23 59 59 999999 dicts article objects filterpubdateyear2008 extraselectdashedvalue 1 valuesheadline dashedvalue self assertequal sortedd items for d in dicts dashedvalue 1 headline article 11 dashedvalue 1 headline article 12 def testextramethodselectargumentwithdashesself if you use select with extra and names containing dashes on a query that s not a values query those extra select values will silently be ignored article objects bulkcreate article headlinearticle 10 pubdatedatetime2005 7 31 12 30 45 articleheadlinearticle 11 pubdatedatetime2008 1 1 article headlinearticle 12 pubdatedatetime2008 12 31 23 59 59 999999 articles article objects filterpubdateyear2008 extra selectdashedvalue 1 undashedvalue 2 self assertequalarticles0 undashedvalue 2 def testcreaterelationwithgettextlazyself notlazy test lazy gettextlazynotlazy article objects createheadlinelazy pubdatedatetime now article article objects get self assertequalarticle headline notlazy test that assign save works with promise objects article headline lazy article save self assertequalarticle headline notlazy test update article objects updateheadlinelazy article article objects get self assertequalarticle headline notlazy still test bulkcreate article objects all delete article objects bulkcreatearticleheadlinelazy pubdatedatetime now article article objects get self assertequalarticle headline notlazy def testemptyqsself msg emptyqueryset can t be instantiated with self assertraisesmessagetypeerror msg emptyqueryset self assertisinstancearticle objects none emptyqueryset self assertnotisinstance emptyqueryset def testemptyqsvaluesself test for 15959 article objects createheadlinefoo pubdatedatetime now with self assertnumqueries0 qs article objects none valueslistpk self assertisinstanceqs emptyqueryset self assertequallenqs 0 def testemptyqscustomqsself a hacky test for custom queryset subclass refs 17271 article objects createheadlinefoo pubdatedatetime now class customquerysetmodels queryset def dosomethingself return did something qs article objects all qs class customqueryset qs qs none with self assertnumqueries0 self assertequallenqs 0 self assertisinstanceqs emptyqueryset self assertequalqs dosomething did something def testemptyqsvaluesorderself tests for ticket 17712 article objects createheadlinefoo pubdatedatetime now with self assertnumqueries0 self assertequal lenarticle objects none valueslistid orderbyid 0 with self assertnumqueries0 self assertequal len article objects none filter idinarticle objects valueslistid flattrue 0 skipunlessdbfeaturecandistinctonfields def testemptyqsdistinctself tests for 19426 article objects createheadlinefoo pubdatedatetime now with self assertnumqueries0 self assertequal lenarticle objects none distinctheadline pubdate 0 def testticket20278self sr selfref objects create with self assertraisesobjectdoesnotexist selfref objects getselfrefsr def testeqself self assertequalarticleid1 articleid1 self assertnotequalarticleid1 object self assertnotequalobject articleid1 a article self assertequala a self assertequala mock any self assertnotequalarticle a def testhashself value based on pk self assertequalhasharticleid1 hash1 msg model instances without primary key value are unhashable with self assertraisesmessagetypeerror msg no pk value unhashable because save would then change hash hasharticle def testmissinghashnotinheritedself class nohashmodels model def eqself other return super eqother with self assertraisesmessagetypeerror unhashable type nohash hashnohashid1 def testspecifiedparenthashinheritedself class parenthashmodels model def eqself other return super eqother hash models model hash self assertequalhashparenthashid1 1 def testdeleteandaccessfieldself accessing a field after it s deleted from a model reloads its value pubdate datetime now article article objects createheadlinefoo pubdatepubdate newpubdate article pubdate timedeltadays10 article headline bar article pubdate newpubdate del article headline with self assertnumqueries1 self assertequalarticle headline foo fields that weren t deleted aren t reloaded self assertequalarticle pubdate newpubdate def testmultipleobjectsmaxnumfetchedself maxresults maxgetresults 1 article objects bulkcreate articleheadlinearea s i pubdatedatetime2005 7 28 for i in rangemaxresults self assertraisesmessage multipleobjectsreturned get returned more than one article it returned d maxresults article objects get headlinestartswitharea article objects create headlinearea s maxresults pubdatedatetime2005 7 28 self assertraisesmessage multipleobjectsreturned get returned more than one article it returned more than d maxresults article objects get headlinestartswitharea class modellookuptesttestcase classmethod def setuptestdatacls create an article cls a article idnone headlineswallow programs in python pubdatedatetime2005 7 28 save it into the database you have to call save explicitly cls a save def testalllookupself change values by changing the attributes then calling save self a headline parrot programs in python self a save article objects all returns all the articles in the database self assertsequenceequalarticle objects all self a def testrichlookupself django provides a rich database lookup api self assertequalarticle objects getidexactself a id self a self assertequalarticle objects getheadlinestartswithswallow self a self assertequalarticle objects getpubdateyear2005 self a self assertequal article objects getpubdateyear2005 pubdatemonth7 self a self assertequal article objects get pubdateyear2005 pubdatemonth7 pubdateday28 self a self assertequalarticle objects getpubdateweekday5 self a def testequallookupself the exact lookup type can be omitted as a shortcut self assertequalarticle objects getidself a id self a self assertequal article objects getheadlineswallow programs in python self a self assertsequenceequal article objects filterpubdateyear2005 self a self assertsequenceequal article objects filterpubdateyear2004 self assertsequenceequal article objects filterpubdateyear2005 pubdatemonth7 self a self assertsequenceequal article objects filterpubdateweekday5 self a self assertsequenceequal article objects filterpubdateweekday6 def testdoesnotexistself django raises an article doesnotexist exception for get if the parameters don t match any object with self assertraisesmessage objectdoesnotexist article matching query does not exist article objects get idexact2000 to avoid dictordering related errors check only one lookup in single assert with self assertraisesobjectdoesnotexist article objects getpubdateyear2005 pubdatemonth8 with self assertraisesmessage objectdoesnotexist article matching query does not exist article objects get pubdateweekday6 def testlookupbyprimarykeyself lookup by a primary key is the most common case so django provides a shortcut for primarykey exact lookups the following is identical to articles getida id self assertequalarticle objects getpkself a id self a pk can be used as a shortcut for the primary key name in any query self assertsequenceequalarticle objects filterpkinself a id self a model instances of the same type and same id are considered equal a article objects getpkself a id b article objects getpkself a id self assertequala b def testtoomanyself create a very similar object a article idnone headlineswallow bites python pubdatedatetime2005 7 28 a save self assertequalarticle objects count 2 django raises an article multipleobjectsreturned exception if the lookup matches more than one object msg get returned more than one article it returned 2 with self assertraisesmessagemultipleobjectsreturned msg article objects get headlinestartswithswallow with self assertraisesmessagemultipleobjectsreturned msg article objects get pubdateyear2005 with self assertraisesmessagemultipleobjectsreturned msg article objects getpubdateyear2005 pubdatemonth7 class concurrentsaveteststransactiontestcase availableapps basic skipunlessdbfeaturetestdballowsmultipleconnections def testconcurrentdeletewithsaveself a article objects createheadlinefoo pubdatedatetime now exceptions def deleter try do not delete a directly doing so alters its state article objects filterpka pk delete except exception as e exceptions appende finally connectionsdefaultdbalias close self assertequallenexceptions 0 t threading threadtargetdeleter t start t join a save self assertequalarticle objects getpka pk headline foo class managertestsimpletestcase querysetproxymethods none count dates datetimes distinct extra get getorcreate updateorcreate create bulkcreate bulkupdate filter aggregate annotate alias complexfilter exclude inbulk iterator earliest latest first last orderby selectforupdate selectrelated prefetchrelated values valueslist update reverse defer only using exists contains explain insert update raw union intersection difference aaggregate abulkcreate abulkupdate acontains acount acreate aearliest aexists aexplain afirst aget agetorcreate ainbulk aiterator alast alatest aupdate aupdateorcreate def testmanagermethodsself self assertequal sortedbasemanager getquerysetmethodsmodels queryset sortedself querysetproxymethods def testmanagermethodattributesself self assertequalarticle objects get doc models queryset get doc self assertequalarticle objects count name models queryset count name def testmanagermethodsignatureself self assertequal strinspect signaturearticle objects bulkcreate objs batchsizenone ignoreconflictsfalse updateconflictsfalse updatefieldsnone uniquefieldsnone class selectonsaveteststestcase def testselectonsaveself a1 article objects createpubdatedatetime now with self assertnumqueries1 a1 save asos articleselectonsave objects createpubdatedatetime now with self assertnumqueries2 asos save with self assertnumqueries1 asos saveforceupdatetrue article objects all delete with self assertraisesmessage databaseerror forced update did not affect any rows with self assertnumqueries1 asos saveforceupdatetrue def testselectonsavelyingupdateself change the manager to not return row matched for update we are going to change the article s basemanager class dynamically this is a bit of a hack but it seems hard to test this properly otherwise article s manager because proxy models use their parent model s basemanager origclass article basemanager querysetclass class fakequerysetmodels queryset make sure the update method below is in fact called called false def updateself args kwargs fakequeryset called true super updateargs kwargs return 0 try article basemanager querysetclass fakequeryset asos articleselectonsave objects createpubdatedatetime now with self assertnumqueries3 asos save self asserttruefakequeryset called this is not wanted behavior but this is how django has always behaved for databases that do not return correct information about matched rows for update with self assertraisesmessage databaseerror forced update did not affect any rows asos saveforceupdatetrue msg an error occurred in the current transaction you can t execute queries until the end of the atomic block with self assertraisesmessagedatabaseerror msg as cm asos saveupdatefieldspubdate self assertisinstancecm exception cause databaseerror finally article basemanager querysetclass origclass class modelrefreshteststestcase def testrefreshself a article objects createpubdatedatetime now article objects createpubdatedatetime now article objects filterpka pk updateheadlinenew headline with self assertnumqueries1 a refreshfromdb self assertequala headline new headline origpubdate a pubdate newpubdate a pubdate timedelta10 article objects updateheadlinenew headline 2 pubdatenewpubdate with self assertnumqueries1 a refreshfromdbfieldsheadline self assertequala headline new headline 2 self assertequala pubdate origpubdate with self assertnumqueries1 a refreshfromdb self assertequala pubdate newpubdate def testunknownkwargself s selfref objects create msg refreshfromdb got an unexpected keyword argument unknownkwarg with self assertraisesmessagetypeerror msg s refreshfromdbunknownkwarg10 def testlookupinfieldsself s selfref objects create msg found in fields argument relations and transforms are not allowed in fields with self assertraisesmessagevalueerror msg s refreshfromdbfieldsfoobar def testrefreshfkself s1 selfref objects create s2 selfref objects create s3 selfref objects createselfrefs1 s3copy selfref objects getpks3 pk s3copy selfref touched true s3 selfref s2 s3 save with self assertnumqueries1 s3copy refreshfromdb with self assertnumqueries1 the old related instance was thrown away the selfrefid has changed it needs to be reloaded on access so one query executed self assertfalsehasattrs3copy selfref touched self assertequals3copy selfref s2 def testrefreshnullfkself s1 selfref objects create s2 selfref objects createselfrefs1 s2 selfref none s2 refreshfromdb self assertequals2 selfref s1 def testrefreshunsavedself pubdate datetime now a article objects createpubdatepubdate a2 articleida pk with self assertnumqueries1 a2 refreshfromdb self assertequala2 pubdate pubdate self assertequala2 state db default def testrefreshfkondeletesetnullself a article objects create headlineparrot programs in python pubdatedatetime2005 7 28 s1 selfref objects createarticlea a delete s1 refreshfromdb self assertisnones1 articleid self assertisnones1 article def testrefreshnofieldsself a article objects createpubdatedatetime now with self assertnumqueries0 a refreshfromdbfields def testrefreshclearsreverserelatedself refreshfromdb without fields relation is cleared and prefetch cache is stale cache was cleared and new results are available refreshfromdb with fields relation is added and prefetch cache is stale cache was cleared and new results are available save it into the database you have to call save explicitly you can initialize a model instance using positional arguments which should match the field order as defined in the model you can also mix and match position and keyword arguments but be sure not to duplicate field information you can leave off the value for an autofield when creating an object because it ll get filled in automatically when you save as much precision in seconds you can use in to test for membership but there will often be more efficient ways if that is all you need an update attempt is skipped when a primary key has default an update attempt is skipped when a primary key has db_default an update attempt is skipped when an inherited primary key has default you can manually specify the primary key when creating a new object you can create saved objects in a single step edge case test a year lookup should retrieve all objects in the given year including jan 1 and dec 31 unicode data works too model instances have a hash function so they can be used in sets or as dictionary keys two models compare as equal if their primary keys are equal the select argument to extra supports names with dashes in them as long as you use values if you use select with extra and names containing dashes on a query that s not a values query those extra select values will silently be ignored gettext_lazy objects work when saving model instances through various methods refs 10498 test that assign save works with promise objects test update still test bulk_create test for 15959 a hacky test for custom queryset subclass refs 17271 tests for ticket 17712 tests for 19426 value based on pk no pk value unhashable because save would then change hash accessing a field after it s deleted from a model reloads its value fields that weren t deleted aren t reloaded create an article save it into the database you have to call save explicitly change values by changing the attributes then calling save article objects all returns all the articles in the database django provides a rich database lookup api the __exact lookup type can be omitted as a shortcut django raises an article doesnotexist exception for get if the parameters don t match any object to avoid dict ordering related errors check only one lookup in single assert lookup by a primary key is the most common case so django provides a shortcut for primary key exact lookups the following is identical to articles get id a id pk can be used as a shortcut for the primary key name in any query model instances of the same type and same id are considered equal create a very similar object django raises an article multipleobjectsreturned exception if the lookup matches more than one object test fetching deleting and finally saving an object we should get an insert in this case do not delete a directly doing so alters its state this test ensures that the correct set of methods from queryset are copied onto manager it s particularly useful to prevent accidentally leaking new methods into manager new queryset methods that should also be copied onto manager will need to be added to managertest queryset_proxy_methods select_on_save works correctly if the database doesn t return correct information about matched rows from update change the manager to not return row matched for update we are going to change the article s _base_manager class dynamically this is a bit of a hack but it seems hard to test this properly otherwise article s manager because proxy models use their parent model s _base_manager make sure the _update method below is in fact called this is not wanted behavior but this is how django has always behaved for databases that do not return correct information about matched rows for update the old related instance was thrown away the selfref_id has changed it needs to be reloaded on access so one query executed refresh_from_db clear cached reverse relations refresh_from_db without fields relation is cleared and prefetch cache is stale cache was cleared and new results are available refresh_from_db with fields relation is added and prefetch cache is stale cache was cleared and new results are available
import inspect
import threading
from datetime import datetime, timedelta
from unittest import mock

from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.db import DEFAULT_DB_ALIAS, DatabaseError, connections, models
from django.db.models.manager import BaseManager
from django.db.models.query import MAX_GET_RESULTS, EmptyQuerySet
from django.test import (
    SimpleTestCase,
    TestCase,
    TransactionTestCase,
    skipUnlessDBFeature,
)
from django.utils.translation import gettext_lazy

from .models import (
    Article,
    ArticleSelectOnSave,
    ChildPrimaryKeyWithDefault,
    FeaturedArticle,
    PrimaryKeyWithDbDefault,
    PrimaryKeyWithDefault,
    SelfRef,
)


class ModelInstanceCreationTests(TestCase):
    def test_object_is_not_written_to_database_until_save_was_called(self):
        a = Article(
            id=None,
            headline="Parrot programs in Python",
            pub_date=datetime(2005, 7, 28),
        )
        self.assertIsNone(a.id)
        self.assertEqual(Article.objects.count(), 0)

        
        a.save()
        self.assertIsNotNone(a.id)
        self.assertEqual(Article.objects.count(), 1)

    def test_can_initialize_model_instance_using_positional_arguments(self):
        
        a = Article(None, "Second article", datetime(2005, 7, 29))
        a.save()

        self.assertEqual(a.headline, "Second article")
        self.assertEqual(a.pub_date, datetime(2005, 7, 29, 0, 0))

    def test_can_create_instance_using_kwargs(self):
        a = Article(
            id=None,
            headline="Third article",
            pub_date=datetime(2005, 7, 30),
        )
        a.save()
        self.assertEqual(a.headline, "Third article")
        self.assertEqual(a.pub_date, datetime(2005, 7, 30, 0, 0))

    def test_autofields_generate_different_values_for_each_instance(self):
        a1 = Article.objects.create(
            headline="First", pub_date=datetime(2005, 7, 30, 0, 0)
        )
        a2 = Article.objects.create(
            headline="First", pub_date=datetime(2005, 7, 30, 0, 0)
        )
        a3 = Article.objects.create(
            headline="First", pub_date=datetime(2005, 7, 30, 0, 0)
        )
        self.assertNotEqual(a3.id, a1.id)
        self.assertNotEqual(a3.id, a2.id)

    def test_can_mix_and_match_position_and_kwargs(self):
        
        
        a = Article(None, "Fourth article", pub_date=datetime(2005, 7, 31))
        a.save()
        self.assertEqual(a.headline, "Fourth article")

    def test_positional_and_keyword_args_for_the_same_field(self):
        msg = "Article() got both positional and keyword arguments for field '%s'."
        with self.assertRaisesMessage(TypeError, msg % "headline"):
            Article(None, "Fifth article", headline="Other headline.")
        with self.assertRaisesMessage(TypeError, msg % "headline"):
            Article(None, "Sixth article", headline="")
        with self.assertRaisesMessage(TypeError, msg % "pub_date"):
            Article(None, "Seventh article", datetime(2021, 3, 1), pub_date=None)

    def test_cannot_create_instance_with_invalid_kwargs(self):
        msg = "Article() got unexpected keyword arguments: 'foo'"
        with self.assertRaisesMessage(TypeError, msg):
            Article(
                id=None,
                headline="Some headline",
                pub_date=datetime(2005, 7, 31),
                foo="bar",
            )
        msg = "Article() got unexpected keyword arguments: 'foo', 'bar'"
        with self.assertRaisesMessage(TypeError, msg):
            Article(
                id=None,
                headline="Some headline",
                pub_date=datetime(2005, 7, 31),
                foo="bar",
                bar="baz",
            )

    def test_can_leave_off_value_for_autofield_and_it_gets_value_on_save(self):
        
        a = Article(headline="Article 5", pub_date=datetime(2005, 7, 31))
        a.save()
        self.assertEqual(a.headline, "Article 5")
        self.assertIsNotNone(a.id)

    def test_leaving_off_a_field_with_default_set_the_default_will_be_saved(self):
        a = Article(pub_date=datetime(2005, 7, 31))
        a.save()
        self.assertEqual(a.headline, "Default headline")

    def test_for_datetimefields_saves_as_much_precision_as_was_given(self):
        
        a1 = Article(
            headline="Article 7",
            pub_date=datetime(2005, 7, 31, 12, 30),
        )
        a1.save()
        self.assertEqual(
            Article.objects.get(id__exact=a1.id).pub_date, datetime(2005, 7, 31, 12, 30)
        )

        a2 = Article(
            headline="Article 8",
            pub_date=datetime(2005, 7, 31, 12, 30, 45),
        )
        a2.save()
        self.assertEqual(
            Article.objects.get(id__exact=a2.id).pub_date,
            datetime(2005, 7, 31, 12, 30, 45),
        )

    def test_saving_an_object_again_does_not_create_a_new_object(self):
        a = Article(headline="original", pub_date=datetime(2014, 5, 16))
        a.save()
        current_id = a.id

        a.save()
        self.assertEqual(a.id, current_id)

        a.headline = "Updated headline"
        a.save()
        self.assertEqual(a.id, current_id)

    def test_querysets_checking_for_membership(self):
        headlines = ["Parrot programs in Python", "Second article", "Third article"]
        some_pub_date = datetime(2014, 5, 16, 12, 1)
        for headline in headlines:
            Article(headline=headline, pub_date=some_pub_date).save()
        a = Article(headline="Some headline", pub_date=some_pub_date)
        a.save()

        
        self.assertIn(a, Article.objects.all())
        
        self.assertTrue(Article.objects.filter(id=a.id).exists())

    def test_save_primary_with_default(self):
        
        with self.assertNumQueries(1):
            PrimaryKeyWithDefault().save()

    def test_save_primary_with_db_default(self):
        
        with self.assertNumQueries(1):
            PrimaryKeyWithDbDefault().save()

    def test_save_parent_primary_with_default(self):
        
        
        with self.assertNumQueries(2):
            ChildPrimaryKeyWithDefault().save()


class ModelTest(TestCase):
    def test_objects_attribute_is_only_available_on_the_class_itself(self):
        with self.assertRaisesMessage(
            AttributeError, "Manager isn't accessible via Article instances"
        ):
            getattr(
                Article(),
                "objects",
            )
        self.assertFalse(hasattr(Article(), "objects"))
        self.assertTrue(hasattr(Article, "objects"))

    def test_queryset_delete_removes_all_items_in_that_queryset(self):
        headlines = ["An article", "Article One", "Amazing article", "Boring article"]
        some_pub_date = datetime(2014, 5, 16, 12, 1)
        for headline in headlines:
            Article(headline=headline, pub_date=some_pub_date).save()
        self.assertQuerySetEqual(
            Article.objects.order_by("headline"),
            sorted(headlines),
            transform=lambda a: a.headline,
        )
        Article.objects.filter(headline__startswith="A").delete()
        self.assertEqual(Article.objects.get().headline, "Boring article")

    def test_not_equal_and_equal_operators_behave_as_expected_on_instances(self):
        some_pub_date = datetime(2014, 5, 16, 12, 1)
        a1 = Article.objects.create(headline="First", pub_date=some_pub_date)
        a2 = Article.objects.create(headline="Second", pub_date=some_pub_date)
        self.assertNotEqual(a1, a2)
        self.assertEqual(a1, Article.objects.get(id__exact=a1.id))

        self.assertNotEqual(
            Article.objects.get(id__exact=a1.id), Article.objects.get(id__exact=a2.id)
        )

    def test_microsecond_precision(self):
        a9 = Article(
            headline="Article 9",
            pub_date=datetime(2005, 7, 31, 12, 30, 45, 180),
        )
        a9.save()
        self.assertEqual(
            Article.objects.get(pk=a9.pk).pub_date,
            datetime(2005, 7, 31, 12, 30, 45, 180),
        )

    def test_manually_specify_primary_key(self):
        
        a101 = Article(
            id=101,
            headline="Article 101",
            pub_date=datetime(2005, 7, 31, 12, 30, 45),
        )
        a101.save()
        a101 = Article.objects.get(pk=101)
        self.assertEqual(a101.headline, "Article 101")

    def test_create_method(self):
        
        a10 = Article.objects.create(
            headline="Article 10",
            pub_date=datetime(2005, 7, 31, 12, 30, 45),
        )
        self.assertEqual(Article.objects.get(headline="Article 10"), a10)

    def test_year_lookup_edge_case(self):
        
        
        a11 = Article.objects.create(
            headline="Article 11",
            pub_date=datetime(2008, 1, 1),
        )
        a12 = Article.objects.create(
            headline="Article 12",
            pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
        )
        self.assertSequenceEqual(
            Article.objects.filter(pub_date__year=2008),
            [a11, a12],
        )

    def test_unicode_data(self):
        
        a = Article(
            headline="\u6797\u539f \u3081\u3050\u307f",
            pub_date=datetime(2005, 7, 28),
        )
        a.save()
        self.assertEqual(
            Article.objects.get(pk=a.id).headline, "\u6797\u539f \u3081\u3050\u307f"
        )

    def test_hash_function(self):
        
        
        
        a10 = Article.objects.create(
            headline="Article 10",
            pub_date=datetime(2005, 7, 31, 12, 30, 45),
        )
        a11 = Article.objects.create(
            headline="Article 11",
            pub_date=datetime(2008, 1, 1),
        )
        a12 = Article.objects.create(
            headline="Article 12",
            pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
        )

        s = {a10, a11, a12}
        self.assertIn(Article.objects.get(headline="Article 11"), s)

    def test_extra_method_select_argument_with_dashes_and_values(self):
        
        
        Article.objects.bulk_create(
            [
                Article(
                    headline="Article 10", pub_date=datetime(2005, 7, 31, 12, 30, 45)
                ),
                Article(headline="Article 11", pub_date=datetime(2008, 1, 1)),
                Article(
                    headline="Article 12",
                    pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
                ),
            ]
        )
        dicts = (
            Article.objects.filter(pub_date__year=2008)
            .extra(select={"dashed-value": "1"})
            .values("headline", "dashed-value")
        )
        self.assertEqual(
            [sorted(d.items()) for d in dicts],
            [
                [("dashed-value", 1), ("headline", "Article 11")],
                [("dashed-value", 1), ("headline", "Article 12")],
            ],
        )

    def test_extra_method_select_argument_with_dashes(self):
        
        
        
        Article.objects.bulk_create(
            [
                Article(
                    headline="Article 10", pub_date=datetime(2005, 7, 31, 12, 30, 45)
                ),
                Article(headline="Article 11", pub_date=datetime(2008, 1, 1)),
                Article(
                    headline="Article 12",
                    pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
                ),
            ]
        )
        articles = Article.objects.filter(pub_date__year=2008).extra(
            select={"dashed-value": "1", "undashedvalue": "2"}
        )
        self.assertEqual(articles[0].undashedvalue, 2)

    def test_create_relation_with_gettext_lazy(self):
        
        notlazy = "test"
        lazy = gettext_lazy(notlazy)
        Article.objects.create(headline=lazy, pub_date=datetime.now())
        article = Article.objects.get()
        self.assertEqual(article.headline, notlazy)
        
        article.headline = lazy
        article.save()
        self.assertEqual(article.headline, notlazy)
        
        Article.objects.update(headline=lazy)
        article = Article.objects.get()
        self.assertEqual(article.headline, notlazy)
        
        Article.objects.all().delete()
        Article.objects.bulk_create([Article(headline=lazy, pub_date=datetime.now())])
        article = Article.objects.get()
        self.assertEqual(article.headline, notlazy)

    def test_emptyqs(self):
        msg = "EmptyQuerySet can't be instantiated"
        with self.assertRaisesMessage(TypeError, msg):
            EmptyQuerySet()
        self.assertIsInstance(Article.objects.none(), EmptyQuerySet)
        self.assertNotIsInstance("", EmptyQuerySet)

    def test_emptyqs_values(self):
        
        Article.objects.create(headline="foo", pub_date=datetime.now())
        with self.assertNumQueries(0):
            qs = Article.objects.none().values_list("pk")
            self.assertIsInstance(qs, EmptyQuerySet)
            self.assertEqual(len(qs), 0)

    def test_emptyqs_customqs(self):
        
        Article.objects.create(headline="foo", pub_date=datetime.now())

        class CustomQuerySet(models.QuerySet):
            def do_something(self):
                return "did something"

        qs = Article.objects.all()
        qs.__class__ = CustomQuerySet
        qs = qs.none()
        with self.assertNumQueries(0):
            self.assertEqual(len(qs), 0)
            self.assertIsInstance(qs, EmptyQuerySet)
            self.assertEqual(qs.do_something(), "did something")

    def test_emptyqs_values_order(self):
        
        Article.objects.create(headline="foo", pub_date=datetime.now())
        with self.assertNumQueries(0):
            self.assertEqual(
                len(Article.objects.none().values_list("id").order_by("id")), 0
            )
        with self.assertNumQueries(0):
            self.assertEqual(
                len(
                    Article.objects.none().filter(
                        id__in=Article.objects.values_list("id", flat=True)
                    )
                ),
                0,
            )

    @skipUnlessDBFeature("can_distinct_on_fields")
    def test_emptyqs_distinct(self):
        
        Article.objects.create(headline="foo", pub_date=datetime.now())
        with self.assertNumQueries(0):
            self.assertEqual(
                len(Article.objects.none().distinct("headline", "pub_date")), 0
            )

    def test_ticket_20278(self):
        sr = SelfRef.objects.create()
        with self.assertRaises(ObjectDoesNotExist):
            SelfRef.objects.get(selfref=sr)

    def test_eq(self):
        self.assertEqual(Article(id=1), Article(id=1))
        self.assertNotEqual(Article(id=1), object())
        self.assertNotEqual(object(), Article(id=1))
        a = Article()
        self.assertEqual(a, a)
        self.assertEqual(a, mock.ANY)
        self.assertNotEqual(Article(), a)

    def test_hash(self):
        
        self.assertEqual(hash(Article(id=1)), hash(1))
        msg = "Model instances without primary key value are unhashable"
        with self.assertRaisesMessage(TypeError, msg):
            
            
            hash(Article())

    def test_missing_hash_not_inherited(self):
        class NoHash(models.Model):
            def __eq__(self, other):
                return super.__eq__(other)

        with self.assertRaisesMessage(TypeError, "unhashable type: 'NoHash'"):
            hash(NoHash(id=1))

    def test_specified_parent_hash_inherited(self):
        class ParentHash(models.Model):
            def __eq__(self, other):
                return super.__eq__(other)

            __hash__ = models.Model.__hash__

        self.assertEqual(hash(ParentHash(id=1)), 1)

    def test_delete_and_access_field(self):
        
        pub_date = datetime.now()
        article = Article.objects.create(headline="foo", pub_date=pub_date)
        new_pub_date = article.pub_date + timedelta(days=10)
        article.headline = "bar"
        article.pub_date = new_pub_date
        del article.headline
        with self.assertNumQueries(1):
            self.assertEqual(article.headline, "foo")
        
        self.assertEqual(article.pub_date, new_pub_date)

    def test_multiple_objects_max_num_fetched(self):
        max_results = MAX_GET_RESULTS - 1
        Article.objects.bulk_create(
            Article(headline="Area %s" % i, pub_date=datetime(2005, 7, 28))
            for i in range(max_results)
        )
        self.assertRaisesMessage(
            MultipleObjectsReturned,
            "get() returned more than one Article -- it returned %d!" % max_results,
            Article.objects.get,
            headline__startswith="Area",
        )
        Article.objects.create(
            headline="Area %s" % max_results, pub_date=datetime(2005, 7, 28)
        )
        self.assertRaisesMessage(
            MultipleObjectsReturned,
            "get() returned more than one Article -- it returned more than %d!"
            % max_results,
            Article.objects.get,
            headline__startswith="Area",
        )


class ModelLookupTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        
        cls.a = Article(
            id=None,
            headline="Swallow programs in Python",
            pub_date=datetime(2005, 7, 28),
        )
        
        cls.a.save()

    def test_all_lookup(self):
        
        self.a.headline = "Parrot programs in Python"
        self.a.save()

        
        self.assertSequenceEqual(Article.objects.all(), [self.a])

    def test_rich_lookup(self):
        
        self.assertEqual(Article.objects.get(id__exact=self.a.id), self.a)
        self.assertEqual(Article.objects.get(headline__startswith="Swallow"), self.a)
        self.assertEqual(Article.objects.get(pub_date__year=2005), self.a)
        self.assertEqual(
            Article.objects.get(pub_date__year=2005, pub_date__month=7), self.a
        )
        self.assertEqual(
            Article.objects.get(
                pub_date__year=2005, pub_date__month=7, pub_date__day=28
            ),
            self.a,
        )
        self.assertEqual(Article.objects.get(pub_date__week_day=5), self.a)

    def test_equal_lookup(self):
        
        self.assertEqual(Article.objects.get(id=self.a.id), self.a)
        self.assertEqual(
            Article.objects.get(headline="Swallow programs in Python"), self.a
        )

        self.assertSequenceEqual(
            Article.objects.filter(pub_date__year=2005),
            [self.a],
        )
        self.assertSequenceEqual(
            Article.objects.filter(pub_date__year=2004),
            [],
        )
        self.assertSequenceEqual(
            Article.objects.filter(pub_date__year=2005, pub_date__month=7),
            [self.a],
        )

        self.assertSequenceEqual(
            Article.objects.filter(pub_date__week_day=5),
            [self.a],
        )
        self.assertSequenceEqual(
            Article.objects.filter(pub_date__week_day=6),
            [],
        )

    def test_does_not_exist(self):
        
        
        with self.assertRaisesMessage(
            ObjectDoesNotExist, "Article matching query does not exist."
        ):
            Article.objects.get(
                id__exact=2000,
            )
        
        
        with self.assertRaises(ObjectDoesNotExist):
            Article.objects.get(pub_date__year=2005, pub_date__month=8)
        with self.assertRaisesMessage(
            ObjectDoesNotExist, "Article matching query does not exist."
        ):
            Article.objects.get(
                pub_date__week_day=6,
            )

    def test_lookup_by_primary_key(self):
        
        
        
        self.assertEqual(Article.objects.get(pk=self.a.id), self.a)

        
        self.assertSequenceEqual(Article.objects.filter(pk__in=[self.a.id]), [self.a])

        
        a = Article.objects.get(pk=self.a.id)
        b = Article.objects.get(pk=self.a.id)
        self.assertEqual(a, b)

    def test_too_many(self):
        
        a = Article(
            id=None,
            headline="Swallow bites Python",
            pub_date=datetime(2005, 7, 28),
        )
        a.save()

        self.assertEqual(Article.objects.count(), 2)

        
        
        msg = "get() returned more than one Article -- it returned 2!"
        with self.assertRaisesMessage(MultipleObjectsReturned, msg):
            Article.objects.get(
                headline__startswith="Swallow",
            )
        with self.assertRaisesMessage(MultipleObjectsReturned, msg):
            Article.objects.get(
                pub_date__year=2005,
            )
        with self.assertRaisesMessage(MultipleObjectsReturned, msg):
            Article.objects.get(pub_date__year=2005, pub_date__month=7)


class ConcurrentSaveTests(TransactionTestCase):
    available_apps = ["basic"]

    @skipUnlessDBFeature("test_db_allows_multiple_connections")
    def test_concurrent_delete_with_save(self):
        
        a = Article.objects.create(headline="foo", pub_date=datetime.now())
        exceptions = []

        def deleter():
            try:
                
                Article.objects.filter(pk=a.pk).delete()
            except Exception as e:
                exceptions.append(e)
            finally:
                connections[DEFAULT_DB_ALIAS].close()

        self.assertEqual(len(exceptions), 0)
        t = threading.Thread(target=deleter)
        t.start()
        t.join()
        a.save()
        self.assertEqual(Article.objects.get(pk=a.pk).headline, "foo")


class ManagerTest(SimpleTestCase):
    QUERYSET_PROXY_METHODS = [
        "none",
        "count",
        "dates",
        "datetimes",
        "distinct",
        "extra",
        "get",
        "get_or_create",
        "update_or_create",
        "create",
        "bulk_create",
        "bulk_update",
        "filter",
        "aggregate",
        "annotate",
        "alias",
        "complex_filter",
        "exclude",
        "in_bulk",
        "iterator",
        "earliest",
        "latest",
        "first",
        "last",
        "order_by",
        "select_for_update",
        "select_related",
        "prefetch_related",
        "values",
        "values_list",
        "update",
        "reverse",
        "defer",
        "only",
        "using",
        "exists",
        "contains",
        "explain",
        "_insert",
        "_update",
        "raw",
        "union",
        "intersection",
        "difference",
        "aaggregate",
        "abulk_create",
        "abulk_update",
        "acontains",
        "acount",
        "acreate",
        "aearliest",
        "aexists",
        "aexplain",
        "afirst",
        "aget",
        "aget_or_create",
        "ain_bulk",
        "aiterator",
        "alast",
        "alatest",
        "aupdate",
        "aupdate_or_create",
    ]

    def test_manager_methods(self):
        
        self.assertEqual(
            sorted(BaseManager._get_queryset_methods(models.QuerySet)),
            sorted(self.QUERYSET_PROXY_METHODS),
        )

    def test_manager_method_attributes(self):
        self.assertEqual(Article.objects.get.__doc__, models.QuerySet.get.__doc__)
        self.assertEqual(Article.objects.count.__name__, models.QuerySet.count.__name__)

    def test_manager_method_signature(self):
        self.assertEqual(
            str(inspect.signature(Article.objects.bulk_create)),
            "(objs, batch_size=None, ignore_conflicts=False, update_conflicts=False, "
            "update_fields=None, unique_fields=None)",
        )


class SelectOnSaveTests(TestCase):
    def test_select_on_save(self):
        a1 = Article.objects.create(pub_date=datetime.now())
        with self.assertNumQueries(1):
            a1.save()
        asos = ArticleSelectOnSave.objects.create(pub_date=datetime.now())
        with self.assertNumQueries(2):
            asos.save()
        with self.assertNumQueries(1):
            asos.save(force_update=True)
        Article.objects.all().delete()
        with self.assertRaisesMessage(
            DatabaseError, "Forced update did not affect any rows."
        ):
            with self.assertNumQueries(1):
                asos.save(force_update=True)

    def test_select_on_save_lying_update(self):
        
        
        
        
        
        

        orig_class = Article._base_manager._queryset_class

        class FakeQuerySet(models.QuerySet):
            
            called = False

            def _update(self, *args, **kwargs):
                FakeQuerySet.called = True
                super()._update(*args, **kwargs)
                return 0

        try:
            Article._base_manager._queryset_class = FakeQuerySet
            asos = ArticleSelectOnSave.objects.create(pub_date=datetime.now())
            with self.assertNumQueries(3):
                asos.save()
                self.assertTrue(FakeQuerySet.called)
            
            
            
            with self.assertRaisesMessage(
                DatabaseError, "Forced update did not affect any rows."
            ):
                asos.save(force_update=True)
            msg = (
                "An error occurred in the current transaction. You can't "
                "execute queries until the end of the 'atomic' block."
            )
            with self.assertRaisesMessage(DatabaseError, msg) as cm:
                asos.save(update_fields=["pub_date"])
            self.assertIsInstance(cm.exception.__cause__, DatabaseError)
        finally:
            Article._base_manager._queryset_class = orig_class


class ModelRefreshTests(TestCase):
    def test_refresh(self):
        a = Article.objects.create(pub_date=datetime.now())
        Article.objects.create(pub_date=datetime.now())
        Article.objects.filter(pk=a.pk).update(headline="new headline")
        with self.assertNumQueries(1):
            a.refresh_from_db()
            self.assertEqual(a.headline, "new headline")

        orig_pub_date = a.pub_date
        new_pub_date = a.pub_date + timedelta(10)
        Article.objects.update(headline="new headline 2", pub_date=new_pub_date)
        with self.assertNumQueries(1):
            a.refresh_from_db(fields=["headline"])
            self.assertEqual(a.headline, "new headline 2")
            self.assertEqual(a.pub_date, orig_pub_date)
        with self.assertNumQueries(1):
            a.refresh_from_db()
            self.assertEqual(a.pub_date, new_pub_date)

    def test_unknown_kwarg(self):
        s = SelfRef.objects.create()
        msg = "refresh_from_db() got an unexpected keyword argument 'unknown_kwarg'"
        with self.assertRaisesMessage(TypeError, msg):
            s.refresh_from_db(unknown_kwarg=10)

    def test_lookup_in_fields(self):
        s = SelfRef.objects.create()
        msg = (
            'Found "__" in fields argument. Relations and transforms are not allowed '
            "in fields."
        )
        with self.assertRaisesMessage(ValueError, msg):
            s.refresh_from_db(fields=["foo__bar"])

    def test_refresh_fk(self):
        s1 = SelfRef.objects.create()
        s2 = SelfRef.objects.create()
        s3 = SelfRef.objects.create(selfref=s1)
        s3_copy = SelfRef.objects.get(pk=s3.pk)
        s3_copy.selfref.touched = True
        s3.selfref = s2
        s3.save()
        with self.assertNumQueries(1):
            s3_copy.refresh_from_db()
        with self.assertNumQueries(1):
            
            
            
            self.assertFalse(hasattr(s3_copy.selfref, "touched"))
            self.assertEqual(s3_copy.selfref, s2)

    def test_refresh_null_fk(self):
        s1 = SelfRef.objects.create()
        s2 = SelfRef.objects.create(selfref=s1)
        s2.selfref = None
        s2.refresh_from_db()
        self.assertEqual(s2.selfref, s1)

    def test_refresh_unsaved(self):
        pub_date = datetime.now()
        a = Article.objects.create(pub_date=pub_date)
        a2 = Article(id=a.pk)
        with self.assertNumQueries(1):
            a2.refresh_from_db()
        self.assertEqual(a2.pub_date, pub_date)
        self.assertEqual(a2._state.db, "default")

    def test_refresh_fk_on_delete_set_null(self):
        a = Article.objects.create(
            headline="Parrot programs in Python",
            pub_date=datetime(2005, 7, 28),
        )
        s1 = SelfRef.objects.create(article=a)
        a.delete()
        s1.refresh_from_db()
        self.assertIsNone(s1.article_id)
        self.assertIsNone(s1.article)

    def test_refresh_no_fields(self):
        a = Article.objects.create(pub_date=datetime.now())
        with self.assertNumQueries(0):
            a.refresh_from_db(fields=[])

    def test_refresh_clears_reverse_related(self):
        
        article = Article.objects.create(
            headline="Parrot programs in Python",
            pub_date=datetime(2005, 7, 28),
        )
        self.assertFalse(hasattr(article, "featured"))
        FeaturedArticle.objects.create(article_id=article.pk)
        article.refresh_from_db()
        self.assertTrue(hasattr(article, "featured"))

    def test_refresh_clears_one_to_one_field(self):
        article = Article.objects.create(
            headline="Parrot programs in Python",
            pub_date=datetime(2005, 7, 28),
        )
        featured = FeaturedArticle.objects.create(article_id=article.pk)
        self.assertEqual(featured.article.headline, "Parrot programs in Python")
        article.headline = "Parrot programs in Python 2.0"
        article.save()
        featured.refresh_from_db()
        self.assertEqual(featured.article.headline, "Parrot programs in Python 2.0")

    def test_prefetched_cache_cleared(self):
        a = Article.objects.create(pub_date=datetime(2005, 7, 28))
        s = SelfRef.objects.create(article=a, article_cited=a)
        
        a1_prefetched = Article.objects.prefetch_related("selfref_set", "cited").first()
        self.assertCountEqual(a1_prefetched.selfref_set.all(), [s])
        self.assertCountEqual(a1_prefetched.cited.all(), [s])
        s.article = None
        s.article_cited = None
        s.save()
        
        self.assertCountEqual(a1_prefetched.selfref_set.all(), [s])
        self.assertCountEqual(a1_prefetched.cited.all(), [s])
        a1_prefetched.refresh_from_db()
        
        self.assertCountEqual(a1_prefetched.selfref_set.all(), [])
        self.assertCountEqual(a1_prefetched.cited.all(), [])
        
        a2_prefetched = Article.objects.prefetch_related("selfref_set", "cited").first()
        self.assertCountEqual(a2_prefetched.selfref_set.all(), [])
        self.assertCountEqual(a2_prefetched.cited.all(), [])
        s.article = a
        s.article_cited = a
        s.save()
        
        self.assertCountEqual(a2_prefetched.selfref_set.all(), [])
        self.assertCountEqual(a2_prefetched.cited.all(), [])
        fields = ["selfref_set", "cited"]
        a2_prefetched.refresh_from_db(fields=fields)
        self.assertEqual(fields, ["selfref_set", "cited"])
        
        self.assertCountEqual(a2_prefetched.selfref_set.all(), [s])
        self.assertCountEqual(a2_prefetched.cited.all(), [s])