Ticket #35974: ticket_35974.patch
File ticket_35974.patch, 8.1 KB (added by , 2 weeks ago) |
---|
-
django/contrib/contenttypes/fields.py
From da74631d9f4a4ecf0267eb2f0cdaa979421d8466 Mon Sep 17 00:00:00 2001 From: Laurent Szyster <laurent.szyster@railnova.eu> Date: Sat, 7 Dec 2024 10:08:19 +0100 Subject: [PATCH] Fixed #35974 - test only _state.adding to assert that an object is unsaved in RelatedManager.add and GenericRelatedObjectManager.add --- django/contrib/contenttypes/fields.py | 2 +- .../db/models/fields/related_descriptors.py | 2 +- tests/multiple_database/fixtures/replica.json | 26 +++++ tests/multiple_database/tests.py | 107 ++++++++++++++++-- 4 files changed, 124 insertions(+), 13 deletions(-) create mode 100644 tests/multiple_database/fixtures/replica.json diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py index a3e87f6ed4..9a9b11ea3c 100644
a b def create_generic_related_manager(superclass, rel): 692 692 if bulk: 693 693 pks = [] 694 694 for obj in objs: 695 if obj._state.adding or obj._state.db != db:695 if obj._state.adding: 696 696 raise ValueError( 697 697 "%r instance isn't saved. Use bulk=False or save " 698 698 "the object first." % obj -
django/db/models/fields/related_descriptors.py
diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index 2b23085fa8..daf8fff131 100644
a b def create_reverse_many_to_one_manager(superclass, rel): 820 820 pks = [] 821 821 for obj in objs: 822 822 check_and_update_obj(obj) 823 if obj._state.adding or obj._state.db != db:823 if obj._state.adding: 824 824 raise ValueError( 825 825 "%r instance isn't saved. Use bulk=False or save " 826 826 "the object first." % obj -
new file tests/multiple_database/fixtures/replica.json
diff --git a/tests/multiple_database/fixtures/replica.json b/tests/multiple_database/fixtures/replica.json new file mode 100644 index 0000000000..c6beb0c111
- + 1 [ 2 { 3 "pk": 1, 4 "model": "multiple_database.book", 5 "fields": { 6 "title": "The Definitive Guide to Django", 7 "published": "2009-7-8" 8 } 9 }, 10 { 11 "pk": 1, 12 "model": "multiple_database.person", 13 "fields": { 14 "name": "Tim Graham" 15 } 16 }, 17 { 18 "pk": 1, 19 "model": "multiple_database.review", 20 "fields": { 21 "source": "Python Weekly", 22 "content_type": 1, 23 "object_id": 1 24 } 25 } 26 ] 27 No newline at end of file -
tests/multiple_database/tests.py
diff --git a/tests/multiple_database/tests.py b/tests/multiple_database/tests.py index 9587030a46..2b9b043ce7 100644
a b class QueryTestCase(TestCase): 1125 1125 review1.content_object = dive 1126 1126 1127 1127 # Add to a foreign key set with an object from a different database 1128 msg = (1129 "<Review: Python Monthly> instance isn't saved. "1130 "Use bulk=False or save the object first."1131 )1132 1128 with self.assertRaisesMessage(ValueError, msg): 1133 1129 with transaction.atomic(using="other"): 1134 1130 dive.reviews.add(review1) … … class RouterTestCase(TestCase): 1502 1498 self.assertEqual(Book.objects.using("default").count(), 1) 1503 1499 self.assertEqual(Book.objects.using("other").count(), 1) 1504 1500 1505 def test_invalid_set_ foreign_key_assignment(self):1501 def test_invalid_set_unsaved_assignment(self): 1506 1502 marty = Person.objects.using("default").create(name="Marty Alchin") 1507 dive = Book .objects.using("other").create(1503 dive = Book( 1508 1504 title="Dive into Python", 1509 1505 published=datetime.date(2009, 5, 4), 1510 1506 ) 1511 1507 # Set a foreign key set with an object from a different database 1512 msg = ( 1513 "<Book: Dive into Python> instance isn't saved. Use bulk=False or save the " 1514 "object first." 1515 ) 1516 with self.assertRaisesMessage(ValueError, msg): 1508 msg = "Model instances without primary key value are unhashable" 1509 with self.assertRaisesMessage(TypeError, msg): 1517 1510 marty.edited.set([dive]) 1518 1511 1519 1512 def test_foreign_key_cross_database_protection(self): … … class RelationAssignmentTests(SimpleTestCase): 2556 2549 profile = UserProfile() 2557 2550 with self.assertRaisesMessage(ValueError, self.router_prevents_msg): 2558 2551 user.userprofile = profile 2552 2553 2554 @override_settings(DATABASE_ROUTERS=[TestRouter()]) 2555 class ReadWriteClusterTests(TestCase): 2556 """see ticket #35974""" 2557 2558 databases = {"default", "other"} 2559 fixtures = ["replica"] 2560 2561 def test_reverse_many_to_one_add(self): 2562 person = Person.objects.get(name="Tim Graham") 2563 book = Book.objects.get(title="The Definitive Guide to Django") 2564 person.edited.add(book) 2565 self.assertEqual( 2566 list(Person.objects.using("default").get(name="Tim Graham").edited.all()), 2567 [book], 2568 ) 2569 2570 def test_reverse_many_to_one_set(self): 2571 person = Person.objects.get(name="Tim Graham") 2572 book = Book.objects.get(title="The Definitive Guide to Django") 2573 person.edited.set([book]) 2574 self.assertEqual( 2575 list(Person.objects.using("default").get(name="Tim Graham").edited.all()), 2576 [book], 2577 ) 2578 2579 def test_reverse_many_to_one_add_unsaved(self): 2580 person = Person.objects.get(name="Tim Graham") 2581 book = Book( 2582 title="The Definitive Guide to Django", 2583 published=datetime.date(2009, 7, 8), 2584 ) 2585 msg = ( 2586 "<Book: The Definitive Guide to Django> instance isn't saved." 2587 " Use bulk=False or save the object first." 2588 ) 2589 with self.assertRaisesMessage(ValueError, msg): 2590 person.edited.add(book) 2591 2592 def test_reverse_many_to_one_set_unsaved(self): 2593 person = Person.objects.get(name="Tim Graham") 2594 book = Book( 2595 title="The Definitive Guide to Django", 2596 published=datetime.date(2009, 7, 8), 2597 ) 2598 msg = "Model instances without primary key value are unhashable" 2599 with self.assertRaisesMessage(TypeError, msg): 2600 person.edited.set([book]) 2601 2602 def test_generic_related_add(self): 2603 book = Book.objects.get(title="The Definitive Guide to Django") 2604 review = Review.objects.get(source="Python Weekly") 2605 book.reviews.add(review) 2606 self.assertEqual( 2607 list( 2608 Book.objects.using("default") 2609 .get(title="The Definitive Guide to Django") 2610 .reviews.all() 2611 ), 2612 [review], 2613 ) 2614 2615 def test_generic_related_set(self): 2616 book = Book.objects.get(title="The Definitive Guide to Django") 2617 review = Review.objects.get(source="Python Weekly") 2618 book.reviews.set([review]) 2619 self.assertEqual( 2620 list( 2621 Book.objects.using("default") 2622 .get(title="The Definitive Guide to Django") 2623 .reviews.all() 2624 ), 2625 [review], 2626 ) 2627 2628 def test_generic_related_add_unsaved(self): 2629 book = Book.objects.get(title="The Definitive Guide to Django") 2630 review = Review(source="Python Weekly") 2631 msg = ( 2632 "<Review: Python Weekly> instance isn't saved." 2633 " Use bulk=False or save the object first." 2634 ) 2635 with self.assertRaisesMessage(ValueError, msg): 2636 book.reviews.add(review) 2637 2638 def test_generic_related_set_unsaved(self): 2639 book = Book.objects.get(title="The Definitive Guide to Django") 2640 review = Review(source="Python Weekly") 2641 msg = "Model instances without primary key value are unhashable" 2642 with self.assertRaisesMessage(TypeError, msg): 2643 book.reviews.set([review])