title: Django: cannot get an Model instance from ForwardManyToOneDescriptor (ForeignKey)
body: <p>I have the following code in <code>accounts/signals/__init__.py</code>:</p>
  
  <pre><code>from django.db.models.signals import post_save
  from django.dispatch import receiver
  from orders.models import Order
  from accounts.models import Balance
  
  @receiver(post_save, sender=Order)
  def update_referral_balance(sender, **kwargs):
      if len(sender.user.referrals_set.all()):
          # TODO: Add referralTransaction
          new_referral_revenue = sender.user.referrals_set.get().revenue
          revenue_from_trade = \
              new_referral_revenue - sender.old_referral_revenue
  
          balance, created = \
              Balance.objects.get(user=sender.user, currency=sender.currency)
          balance.balance += revenue_from_trade
          balance.save()
  </code></pre>
  
  <p>Now, when running tests I am getting the following </p>
  
  <pre><code>error:======================================================================
      ERROR: test_orders_with_approved_payments (payments.tests.test_views.PaymentReleaseTestCase)
      ----------------------------------------------------------------------
      Traceback (most recent call last):
        File "/pipeline/source/payments/tests/test_views.py", line 75, in setUp
          self.order.save()
        File "/pipeline/source/orders/models.py", line 63, in save
          super(Order, self).save(*args, **kwargs)
        File "/usr/local/lib/python3.5/site-packages/safedelete/models.py", line 64, in save
          super(Model, self).save(**kwargs)
        File "/usr/local/lib/python3.5/site-packages/django/db/models/base.py", line 708, in save
          force_update=force_update, update_fields=update_fields)
        File "/usr/local/lib/python3.5/site-packages/django/db/models/base.py", line 745, in save_base
          update_fields=update_fields, raw=raw, using=using)
        File "/usr/local/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 192, in send
          response = receiver(signal=self, sender=sender, **named)
        File "/pipeline/source/accounts/signals/__init__.py", line 9, in update_referral_balance
          if len(sender.user.referral_set.all()):
      AttributeError: 'ForwardManyToOneDescriptor' object has no attribute 'referral_set'
  </code></pre>
  
  <p>And indeed, when running through it in debugger, I see that the <code>sender.user</code> attribute is something of instance <code>ForwardManyToOneDescriptor</code>:</p>
  
  <pre><code>ipdb&gt; pprint(sender.__dict__['user'].__dict__)
  {'cache_name': '_user_cache',
   'field': &lt;django.db.models.fields.related.ForeignKey: user&gt;}
  </code></pre>
  
  <p>What am I doing wrong?</p>
  
  <p>EDIT: My <code>Order</code> Model:</p>
  
  <p>class Order(TimeStampedModel, SoftDeletableModel, UniqueFieldMixin):
      USD = "USD"
      RUB = "RUB"
      EUR = "EUR"</p>
  
  <pre><code>BUY = 1
  SELL = 0
  TYPES = (
      (SELL, 'SELL'),
      (BUY, 'BUY'),
  )
  
  # Todo: inherit from BTC base?, move lengths to settings?
  order_type = models.IntegerField(choices=TYPES, default=BUY)
  amount_cash = models.DecimalField(max_digits=12, decimal_places=2)
  amount_btc = models.DecimalField(max_digits=18, decimal_places=8)
  currency = models.ForeignKey(Currency)
  payment_window = models.IntegerField(default=settings.PAYMENT_WINDOW)
  user = models.ForeignKey(User, related_name='orders')
  is_paid = models.BooleanField(default=False)
  is_released = models.BooleanField(default=False)
  is_completed = models.BooleanField(default=False)
  is_failed = models.BooleanField(default=False)
  unique_reference = models.CharField(
      max_length=settings.UNIQUE_REFERENCE_LENGTH, unique=True)
  admin_comment = models.CharField(max_length=200)
  payment_preference = models.ForeignKey('payments.PaymentPreference',
                                         default=None,
                                         null=True)
  
  class Meta:
      ordering = ['-created_on']
  
  def save(self, *args, **kwargs):
      self.unique_reference = \
          self.gen_unique_value(
              lambda x: get_random_string(x),
              lambda x: Order.objects.filter(unique_reference=x).count(),
              settings.UNIQUE_REFERENCE_LENGTH
          )
      self.convert_coin_to_cash()
  
      if 'is_completed' in kwargs and\
              kwargs['is_completed'] and\
              not self.is_completed:
          self.old_referral_revenue = \
              self.user.referral_set.get().revenue
  
      super(Order, self).save(*args, **kwargs)
  
  def convert_coin_to_cash(self):
      self.amount_btc = Decimal(self.amount_btc)
      queryset = Price.objects.filter().order_by('-id')[:2]
      price_sell = [price for price in queryset if price.type == Price.SELL]
      price_buy = [price for price in queryset if price.type == Price.BUY]
  
      # Below calculation affect real money the client pays
      assert all([len(price_sell),
                  price_sell[0].price_usd,
                  price_buy[0].price_rub,
                  price_buy[0].price_eur])
  
      assert all([len(price_buy),
                  price_buy[0].price_usd,
                  price_buy[0].price_rub,
                  price_buy[0].price_eur])
  
      # TODO: Make this logic more generic,
      # TODO: migrate to using currency through payment_preference
  
      # SELL
      self.amount_cash = Decimal(self.amount_btc)
  
      if self.order_type == Order.SELL and self.currency.code == Order.USD:
          self.amount_cash *= price_buy[0].price_usd
  
      elif self.order_type == Order.SELL and self.currency.code == Order.RUB:
          self.amount_cash *= price_buy[0].price_rub
  
      elif self.order_type == Order.SELL and self.currency.code == Order.EUR:
          self.amount_cash *= price_buy[0].price_eur
  
      # BUY
      if self.order_type == Order.BUY and self.currency.code == Order.USD:
          self.amount_cash *= price_sell[0].price_usd
  
      elif self.order_type == Order.BUY and self.currency.code == Order.RUB:
          self.amount_cash *= price_sell[0].price_rub
  
      elif self.order_type == Order.BUY and self.currency.code == Order.EUR:
          self.amount_cash *= price_sell[0].price_eur
  
      self.amount_cash = money_format(self.amount_cash)
  
  @property
  def is_buy(self):
      return self.order_type
  
  @property
  def payment_deadline(self):
      """returns datetime of payment_deadline (creation + payment_window)"""
      # TODO: Use this for pay until message on 'order success' screen
      return self.created_on + timedelta(minutes=self.payment_window)
  
  @property
  def expired(self):
      """Is expired if payment_deadline is exceeded and it's not paid yet"""
      # TODO: validate this business rule
      # TODO: Refactor, it is unreasonable to have different standards of
      # time in the DB
      return (timezone.now() &gt; self.payment_deadline) and\
             (not self.is_paid) and not self.is_released
  
  @property
  def payment_status_frozen(self):
      """return a boolean indicating if order can be updated
      Order is frozen if it is expired or has been paid
      """
      # TODO: validate this business rule
      return self.expired or \
          (self.is_paid and
           self.payment_set.last() and
           self.payment_set.last().
           payment_preference.
           payment_method.is_internal)
  
  @property
  def withdrawal_address_frozen(self):
      """return bool whether the withdraw address can
         be changed"""
      return self.is_released
  
  @property
  def has_withdraw_address(self):
      """return a boolean indicating if order has a withdraw adrress defined
      """
      # TODO: Validate this business rule
      return len(self.address_set.all()) &gt; 0
  
  @property
  def withdraw_address(self):
      addr = None
  
      if self.has_withdraw_address:
          addr = self.transaction_set.first().address_to.address
  
      return addr
  
  def __str__(self):
      return "{} {} {} BTC {} {}".format(self.user.username or
                                         self.user.profile.phone,
                                         self.order_type,
                                         self.amount_btc,
                                         self.amount_cash,
                                         self.currency)
  </code></pre>