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

后端 未结 19 1281
清酒与你
清酒与你 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:51

    If you want a simple one-line solution that doesn't involve exception handling, conditional statements or a requirement of Django 1.6+, do this instead:

    x = next(iter(SomeModel.objects.filter(foo='bar')), None)
    
    0 讨论(0)
  • 2020-11-28 01:52

    I use Django 2.2.16. And this is how I solve this problem:

    from typing import Any
    
    from django.core.exceptions import ObjectDoesNotExist
    from django.db import models
    from django.db.models.base import ModelBase
    from django.db.models.manager import Manager
    
    
    class SManager(Manager):
        def get_if_exist(self, *args: Any, **kwargs: Any):
            try:
                return self.get(*args, **kwargs)
            except ObjectDoesNotExist:
                return None
    
    
    class SModelBase(ModelBase):
        def _prepare(cls):
            manager = SManager()
            manager.auto_created = True
            cls.add_to_class("objects", manager)
    
            super()._prepare()
    
        class Meta:
            abstract = True
    
    
    class SModel(models.Model, metaclass=SModelBase):
        managers = False
    
        class Meta:
            abstract = True
    

    And after that, in every models, you just need to import in:

    from custom.models import SModel
    
    
    class SUser(SModel):
        pass
    

    And in views, you can call like this:

    SUser.objects.get_if_exist(id=1)
    
    0 讨论(0)
  • 2020-11-28 01:54

    To make things easier, here is a snippet of the code I wrote, based on inputs from the wonderful replies here:

    class MyManager(models.Manager):
    
        def get_or_none(self, **kwargs):
            try:
                return self.get(**kwargs)
            except ObjectDoesNotExist:
                return None
    

    And then in your model:

    class MyModel(models.Model):
        objects = MyManager()
    

    That's it. Now you have MyModel.objects.get() as well as MyModel.objetcs.get_or_none()

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

    This is a copycat from Django's get_object_or_404 except that the method returns None. This is extremely useful when we have to use only() query to retreive certain fields only. This method can accept a model or a queryset.

    from django.shortcuts import _get_queryset
    
    
    def get_object_or_none(klass, *args, **kwargs):
        """
        Use get() to return an object, or return None if object
        does not exist.
        klass may be a Model, Manager, or QuerySet object. All other passed
        arguments and keyword arguments are used in the get() query.
        Like with QuerySet.get(), MultipleObjectsReturned is raised if more than
        one object is found.
        """
        queryset = _get_queryset(klass)
        if not hasattr(queryset, 'get'):
            klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
            raise ValueError(
                "First argument to get_object_or_none() must be a Model, Manager, "
                "or QuerySet, not '%s'." % klass__name
            )
        try:
            return queryset.get(*args, **kwargs)
        except queryset.model.DoesNotExist:
            return None
    
    0 讨论(0)
  • 2020-11-28 02:00

    Since django 1.6 you can use first() method like so:

    Content.objects.filter(name="baby").first()
    
    0 讨论(0)
  • 2020-11-28 02:00

    Without exception:

    if SomeModel.objects.filter(foo='bar').exists():
        x = SomeModel.objects.get(foo='bar')
    else:
        x = None
    

    Using an exception:

    try:
       x = SomeModel.objects.get(foo='bar')
    except SomeModel.DoesNotExist:
       x = None
    

    There is a bit of an argument about when one should use an exception in python. On the one hand, "it is easier to ask for forgiveness than for permission". While I agree with this, I believe that an exception should remain, well, the exception, and the "ideal case" should run without hitting one.

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