How do I get the object if it exists, or None if it does not exist?

后端 未结 19 1280
清酒与你
清酒与你 2020-11-28 01:14

When I ask the model manager to get an object, it raises DoesNotExist when there is no matching object.

go = Content.objects.get(name=\"baby\")
         


        
相关标签:
19条回答
  • 2020-11-28 01:43

    Handling exceptions at different points in your views could really be cumbersome..What about defining a custom Model Manager, in the models.py file, like

    class ContentManager(model.Manager):
        def get_nicely(self, **kwargs):
            try:
                return self.get(kwargs)
            except(KeyError, Content.DoesNotExist):
                return None
    

    and then including it in the content Model class

    class Content(model.Model):
        ...
        objects = ContentManager()
    

    In this way it can be easily dealt in the views i.e.

    post = Content.objects.get_nicely(pk = 1)
    if post:
        # Do something
    else:
        # This post doesn't exist
    
    0 讨论(0)
  • 2020-11-28 01:44

    It's one of those annoying functions that you might not want to re-implement:

    from annoying.functions import get_object_or_None
    #...
    user = get_object_or_None(Content, name="baby")
    
    0 讨论(0)
  • 2020-11-28 01:45

    you could use exists with a filter:

    Content.objects.filter(name="baby").exists()
    #returns False or True depending on if there is anything in the QS
    

    just an alternative for if you only want to know if it exists

    0 讨论(0)
  • 2020-11-28 01:47

    Maybe is better you use:

    User.objects.filter(username=admin_username).exists()
    
    0 讨论(0)
  • 2020-11-28 01:50

    From django 1.7 onwards you can do like:

    class MyQuerySet(models.QuerySet):
    
        def get_or_none(self, **kwargs):
            try:
                return self.get(**kwargs)
            except self.model.DoesNotExist:
                return None
    
    
    class MyBaseModel(models.Model):
    
        objects = MyQuerySet.as_manager()
    
    
    class MyModel(MyBaseModel):
        ...
    
    class AnotherMyModel(MyBaseModel):
        ...
    

    The advantage of "MyQuerySet.as_manager()" is that both of the following will work:

    MyModel.objects.filter(...).get_or_none()
    MyModel.objects.get_or_none()
    
    0 讨论(0)
  • 2020-11-28 01:50

    I was facing with the same problem too. It's hard to write and read try-except for each time when you want to get an element from your model as in @Arthur Debert's answer. So, my solution is to create an Getter class which is inherited by the models:

    class Getter:
        @classmethod
        def try_to_get(cls, *args, **kwargs):
            try:
                return cls.objects.get(**kwargs)
            except Exception as e:
                return None
    
    class MyActualModel(models.Model, Getter):
        pk_id = models.AutoField(primary_key=True)
        ...
    

    In this way, I can get the actual element of MyActualModel or None:

    MyActualModel.try_to_get(pk_id=1)
    
    0 讨论(0)
提交回复
热议问题