我们从Python开源项目中,提取了以下4个代码示例,用于说明如何使用django.db.router.allow_relation()。
def __set__(self, instance, value): """ Set the related instance through the reverse relation. With the example above, when setting ``place.restaurant = restaurant``: - ``self`` is the descriptor managing the ``restaurant`` attribute - ``instance`` is the ``place`` instance - ``value`` is the ``restaurant`` instance on the right of the equal sign Keep in mind that ``Restaurant`` holds the foreign key to ``Place``. """ # The similarity of the code below to the code in # ForwardManyToOneDescriptor is annoying, but there's a bunch # of small differences that would make a common base class convoluted. if value is None: # Update the cached related instance (if any) & clear the cache. try: rel_obj = getattr(instance, self.cache_name) except AttributeError: pass else: delattr(instance, self.cache_name) setattr(rel_obj, self.related.field.name, None) elif not isinstance(value, self.related.related_model): # An object must be an instance of the related class. raise ValueError( 'Cannot assign "%r": "%s.%s" must be a "%s" instance.' % ( value, instance._meta.object_name, self.related.get_accessor_name(), self.related.related_model._meta.object_name, ) ) else: if instance._state.db is None: instance._state.db = router.db_for_write(instance.__class__, instance=value) elif value._state.db is None: value._state.db = router.db_for_write(value.__class__, instance=instance) elif value._state.db is not None and instance._state.db is not None: if not router.allow_relation(value, instance): raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value) related_pk = tuple(getattr(instance, field.attname) for field in self.related.field.foreign_related_fields) # Set the value of the related field to the value of the related object's related field for index, field in enumerate(self.related.field.local_related_fields): setattr(value, field.attname, related_pk[index]) # Set the related instance cache used by __get__ to avoid an SQL query # when accessing the attribute we just set. setattr(instance, self.cache_name, value) # Set the forward accessor cache on the related object to the current # instance to avoid an extra SQL query if it's accessed later on. setattr(value, self.related.field.get_cache_name(), instance)
def __set__(self, instance, value): # The similarity of the code below to the code in # ReverseSingleRelatedObjectDescriptor is annoying, but there's a bunch # of small differences that would make a common base class convoluted. # If null=True, we can assign null here, but otherwise the value needs # to be an instance of the related class. if value is None and self.related.field.null is False: raise ValueError( 'Cannot assign None: "%s.%s" does not allow null values.' % ( instance._meta.object_name, self.related.get_accessor_name(), ) ) elif value is not None and not isinstance(value, self.related.related_model): raise ValueError( 'Cannot assign "%r": "%s.%s" must be a "%s" instance.' % ( value, instance._meta.object_name, self.related.get_accessor_name(), self.related.related_model._meta.object_name, ) ) elif value is not None: if instance._state.db is None: instance._state.db = router.db_for_write(instance.__class__, instance=value) elif value._state.db is None: value._state.db = router.db_for_write(value.__class__, instance=instance) elif value._state.db is not None and instance._state.db is not None: if not router.allow_relation(value, instance): raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value) related_pk = tuple(getattr(instance, field.attname) for field in self.related.field.foreign_related_fields) if not self.related.field.allow_unsaved_instance_assignment and None in related_pk: raise ValueError( 'Cannot assign "%r": "%s" instance isn\'t saved in the database.' % (value, instance._meta.object_name) ) # Set the value of the related field to the value of the related object's related field for index, field in enumerate(self.related.field.local_related_fields): setattr(value, field.attname, related_pk[index]) # Since we already know what the related object is, seed the related # object caches now, too. This avoids another db hit if you get the # object you just set. setattr(instance, self.cache_name, value) setattr(value, self.related.field.get_cache_name(), instance)