Check if a OneToOne relation exists in Django

前端 未结 3 1261
無奈伤痛
無奈伤痛 2021-01-01 14:27

Now I\'m using django 1.6

I have two models relates with a OneToOneField.

class A(models.Model):
    pass

class B(models.Model):
    re         


        
相关标签:
3条回答
  • 2021-01-01 14:44

    So you have a least two ways of checking that. First is to create try/catch block to get attribute, second is to use hasattr.

    class A(models.Model):
       def get_B(self):
           try:
              return self.b
           except:
              return None
    
    class B(models.Model):
       ref_a = models.OneToOneField(related_name='ref_b', null=True)
    

    Please try to avoid bare except: clauses. It can hide some problems.

    The second way is:

    class A(models.Model):
        def get_B(self):
           if(hasattr(self, 'b')):
               return self.b
           return None
    
    class B(models.Model):
        ref_a = models.OneToOneField(related_name='ref_b', null=True)
    

    In both cases you can use it without any exceptions:

    a1 = A.objects.create()
    a2 = A.objects.create()
    b1 = B.objects.create()
    b2 = B.objects.create(ref_a=a2)
    
    # then I call:
    print(a1.get_b)  # No exception raised
    print(a2.get_b)  # returns b2
    print(b1.a)  # returns None
    print(b2.a)  # returns a2
    

    There is no other way, as throwing the exception is default behaviour from Django One to One relationships.

    And this is the example of handling it from official documentation.

    >>> from django.core.exceptions import ObjectDoesNotExist
    >>> try:
    >>>     p2.restaurant
    >>> except ObjectDoesNotExist:
    >>>     print("There is no restaurant here.")
    There is no restaurant here.
    
    0 讨论(0)
  • 2021-01-01 14:47

    Individual model classes provide a more specific exception called DoesNotExist that extends ObjectDoesNotExist. My preference is to write it this way:

    b = None
    try:
        b = a.ref_b
    except B.DoesNotExist:
        pass
    
    0 讨论(0)
  • 2021-01-01 14:54

    hasattr works fine with Django1.11 ! You may use getattr for shorter version:

    getattr(self, 'field', default)
    

    In your case

    b = getattr(a, 'ref_b', None)
    

    https://docs.python.org/3.6/library/functions.html#getattr

    0 讨论(0)
提交回复
热议问题