Not sure if this is how it was designed but it looks like a bug for me :
Here I have two models, the Review has a one-to-one relation with the OrderProduct
class OrderProduct(BaseModel):
unit_price = models.DecimalField(
_("unit price"), max_digits=9, decimal_places=0)
count = models.PositiveIntegerField(_("count"))
product = models.ForeignKey(
ProductSKU, verbose_name=_("sku"), on_delete=models.CASCADE, related_name='order_products')
order = models.ForeignKey(Order, verbose_name=_(
'Order'), on_delete=models.SET_NULL, null=True, related_name='order_products')
class Review(BaseModel):
class Star(models.IntegerChoices):
VS = 5, _('Very satisfied')
ST = 4, _('Satisfied')
NT = 3, _('Neutral')
US = 2, _('Unsatisfied')
VN = 1, _('Very unsatisfied')
star = models.PositiveSmallIntegerField(
_("stars"), choices=Star.choices, default=5)
comment = models.TextField(_("comment"))
order_product = models.OneToOneField(
OrderProduct, verbose_name=_("order product"), on_delete=models.CASCADE,related_name='review')
Now, I am trying to add a new property to OrderProduct to check if it has been reviewed.
According to the official doc: https://docs.djangoproject.com/en/3.1/topics/db/examples/one_to_one/
I add this code to my OrderProduct model:
@property
def is_reviewed(self):
return hasattr(self, 'review')
I am expecting this property will return true or false when I refer to it, while I always got this exception:
In [38]: hasattr(ob,'review')
Out[38]: False
In [39]: ob.is_reviewed
---------------------------------------------------------------------------
RelatedObjectDoesNotExist Traceback (most recent call last)
<ipython-input-39-1cec125b3605> in <module>
----> 1 ob.is_reviewed
/usr/src/app/apps/order/models.py in is_reviewed(self)
168
169 @property
--> 170 def is_reviewed(self):
171 return hasattr(self, 'review')
172
/usr/local/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py in __get__(self, instance, cls)
419
420 if rel_obj is None:
--> 421 raise self.RelatedObjectDoesNotExist(
422 "%s has no %s." % (
423 instance.__class__.__name__,
RelatedObjectDoesNotExist: OrderProduct has no review.
What I have tried:
I tried to use try/except instead:
@property
def is_reviewed(self):
try:
self.review
return False
except ObjectDoesNotExist:
return True
And still got the same RelatedObjectDoesNotExist exception.
I also tried to replace ObjectDoesNotExist with Review.DoesNotExist, or even only except, remove property decorator, remove related_name in oder_product, and all returned the same error message.
Also, when I try to create a Review object from related manager it throws the same error:
order_product = OrderProduct.objects.get(id=order_product_id)
order_product.review.create(star=star, comment=comment)
Why this exception cannot be caught? Or it is just my mistake on implementation? If so how to fix it? Just want to check whether the related object exists… Really appreciate your help!