@@ -376,14 +376,24 @@ def __set__(self, instance, value):
376
376
377
377
# If null=True, we can assign null here, but otherwise the value needs
378
378
# to be an instance of the related class.
379
- if value is None and self .related .field .null is False :
380
- raise ValueError (
381
- 'Cannot assign None: "%s.%s" does not allow null values.' % (
382
- instance ._meta .object_name ,
383
- self .related .get_accessor_name (),
379
+ if value is None :
380
+ if self .related .field .null :
381
+ # Update the cached related instance (if any) & clear the cache.
382
+ try :
383
+ rel_obj = getattr (instance , self .cache_name )
384
+ except AttributeError :
385
+ pass
386
+ else :
387
+ delattr (instance , self .cache_name )
388
+ setattr (rel_obj , self .related .field .name , None )
389
+ else :
390
+ raise ValueError (
391
+ 'Cannot assign None: "%s.%s" does not allow null values.' % (
392
+ instance ._meta .object_name ,
393
+ self .related .get_accessor_name (),
394
+ )
384
395
)
385
- )
386
- elif value is not None and not isinstance (value , self .related .related_model ):
396
+ elif not isinstance (value , self .related .related_model ):
387
397
raise ValueError (
388
398
'Cannot assign "%r": "%s.%s" must be a "%s" instance.' % (
389
399
value ,
@@ -392,7 +402,7 @@ def __set__(self, instance, value):
392
402
self .related .related_model ._meta .object_name ,
393
403
)
394
404
)
395
- elif value is not None :
405
+ else :
396
406
if instance ._state .db is None :
397
407
instance ._state .db = router .db_for_write (instance .__class__ , instance = value )
398
408
elif value ._state .db is None :
@@ -401,18 +411,18 @@ def __set__(self, instance, value):
401
411
if not router .allow_relation (value , instance ):
402
412
raise ValueError ('Cannot assign "%r": the current database router prevents this relation.' % value )
403
413
404
- related_pk = tuple (getattr (instance , field .attname ) for field in self .related .field .foreign_related_fields )
405
- # Set the value of the related field to the value of the related object's related field
406
- for index , field in enumerate (self .related .field .local_related_fields ):
407
- setattr (value , field .attname , related_pk [index ])
414
+ related_pk = tuple (getattr (instance , field .attname ) for field in self .related .field .foreign_related_fields )
415
+ # Set the value of the related field to the value of the related object's related field
416
+ for index , field in enumerate (self .related .field .local_related_fields ):
417
+ setattr (value , field .attname , related_pk [index ])
408
418
409
- # Set the related instance cache used by __get__ to avoid a SQL query
410
- # when accessing the attribute we just set.
411
- setattr (instance , self .cache_name , value )
419
+ # Set the related instance cache used by __get__ to avoid a SQL query
420
+ # when accessing the attribute we just set.
421
+ setattr (instance , self .cache_name , value )
412
422
413
- # Set the forward accessor cache on the related object to the current
414
- # instance to avoid an extra SQL query if it's accessed later on.
415
- setattr (value , self .related .field .get_cache_name (), instance )
423
+ # Set the forward accessor cache on the related object to the current
424
+ # instance to avoid an extra SQL query if it's accessed later on.
425
+ setattr (value , self .related .field .get_cache_name (), instance )
416
426
417
427
418
428
class ReverseManyToOneDescriptor (object ):
0 commit comments