Ticket #14615: 14615.diff

File 14615.diff, 4.8 KB (added by lukeplant, 4 years ago)

patch - throw exception rather than do a query for unsaved instances

  • django/db/models/base.py

    diff -r 24c30016c52f django/db/models/base.py
    a b  
    585585        return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True)
    586586
    587587    def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs):
    588         if not self.pk:
     588        if self._state.adding:
    589589            raise ValueError("get_next/get_previous cannot be used on unsaved objects.")
    590590        op = is_next and 'gt' or 'lt'
    591591        order = not is_next and '-' or ''
  • django/db/models/fields/related.py

    diff -r 24c30016c52f django/db/models/fields/related.py
    a b  
    223223        try:
    224224            return getattr(instance, self.cache_name)
    225225        except AttributeError:
     226            if instance._state.adding:
     227                raise ValueError("Cannot retrieve related objects until the instance has been saved")
     228
    226229            params = {'%s__pk' % self.related.field.name: instance._get_pk_val()}
    227230            db = router.db_for_read(self.related.model, instance=instance)
    228231            rel_obj = self.related.model._base_manager.using(db).get(**params)
     
    454457
    455458        manager = RelatedManager()
    456459        attname = rel_field.rel.get_related_field().name
     460
     461        if instance._state.adding:
     462            raise ValueError("Cannot retrieve related objects until the instance has been saved")
    457463        manager.core_filters = {'%s__%s' % (rel_field.name, attname):
    458464                getattr(instance, attname)}
    459465        manager.model = self.related.model
     
    478484            self.through = through
    479485            self._pk_val = self.instance.pk
    480486            self.reverse = reverse
    481             if self._pk_val is None:
    482                 raise ValueError("%r instance needs to have a primary key value before a many-to-many relationship can be used." % instance.__class__.__name__)
     487            if self.instance._state.adding:
     488                raise ValueError("%r instance needs to be saved before a many-to-many relationship can be used." % instance.__class__.__name__)
    483489
    484490        def get_query_set(self):
    485491            db = self._db or router.db_for_read(self.instance.__class__, instance=self.instance)
  • tests/modeltests/lookup/tests.py

    diff -r 24c30016c52f tests/modeltests/lookup/tests.py
    a b  
    350350                         '<Article: Article 2>')
    351351        self.assertEqual(repr(self.a2.get_previous_by_pub_date()),
    352352                         '<Article: Article 1>')
     353        self.assertRaises(ValueError, lambda: Article().get_previous_by_pub_date())
    353354
    354355    def test_escaping(self):
    355356        # Underscores, percent signs and backslashes have special meaning in the
  • tests/modeltests/many_to_one/tests.py

    diff -r 24c30016c52f tests/modeltests/many_to_one/tests.py
    a b  
    370370        self.r.cached_query = Article.objects.filter(reporter=self.r)
    371371        from copy import deepcopy
    372372        self.assertEqual(repr(deepcopy(self.r)), "<Reporter: John Smith>")
     373
     374    def test_related_before_save(self):
     375        # You cannot get the related objects before the main object is saved.
     376        # See ticket #14615
     377        self.assertRaises(ValueError, getattr, Reporter(), 'article_set')
  • tests/modeltests/one_to_one/tests.py

    diff -r 24c30016c52f tests/modeltests/one_to_one/tests.py
    a b  
    117117        mm = MultiModel(link1=self.p2, link2=o1, name="x1")
    118118        self.assertRaises(IntegrityError, mm.save)
    119119        transaction.savepoint_rollback(sid)
     120
     121    def test_related_before_save(self):
     122        # You cannot get the related objects before the main object is saved.
     123        # See ticket #14615
     124        self.assertRaises(ValueError, getattr, Place(), 'restaurant')
  • tests/regressiontests/null_queries/tests.py

    diff -r 24c30016c52f tests/regressiontests/null_queries/tests.py
    a b  
    4242        # Can't use None on anything other than __exact
    4343        self.assertRaises(ValueError, Choice.objects.filter, foo__gt=None)
    4444
    45         # Related managers use __exact=None implicitly if the object hasn't been saved.
    46         p2 = Poll(question="How?")
    47         self.assertEquals(repr(p2.choice_set.all()), '[]')
    48 
    4945    def test_reverse_relations(self):
    5046        """
    5147        Querying across reverse relations and then another relation should
Back to Top