简体   繁体   中英

Django - Using defaults if query fails

I am trying to create a script which will retrieve a user account and at the same time that particular users account 'theme' in one simple query. Here is the code I am using, please note the get_account method:

class AccountManager(Manager):
    def __init__(self, *args, **kwargs):
        super(AccountManager, self).__init__(*args, **kwargs)

    def get_account(self, slug):
        return get_object_or_404(self.select_related('theme'), status__exact=self.model.ACTIVE_STATUS, slug__exact=slug)

It works nicely, but if for whatever reason the 'theme' object returns null (this should never happen but I want to be sure!), it will redirect to a 404 page. What I want it to do is check if the theme object exists and is valid, and if not, default to the standard theme and carry on.

I would still like the query to throw a 404 if the user account is not valid though. Short of using a bucket load of try/exceptions, is there a nice clean way of doing this? I like to keep my Managers nice and tidy :)

Hope someone can help

try:
    account = self.select_related('theme').get(
                 status__exact=self.model.ACTIVE_STATUS, slug__exact=slug
              )
except self.model.DoesNotExist:
    account = self.select_related('theme').get(slug="default_slug")

return account

In your example, it wouldn't result in a 404 if the related theme was null as it is not the object being retrieved with get_object_or_404(). It will only 404 if it can't find an Account object that is both ACTIVE_STATUS and a matching slug.

My suggestion to ensure you use a default theme with any valid Account object is:

class AccountManager(Manager):
    def __init__(self, *args, **kwargs):
        super(AccountManager, self).__init__(*args, **kwargs)

    def get_account(self, slug):
        account = get_object_or_404(self.select_related('theme'), status__exact=self.model.ACTIVE_STATUS, slug__exact=slug)
        if not account.theme:
            account.theme = default_theme_obj
        return account

I'll leave it up to you to determine how you would get default_theme_obj as I don't know your models, caching structure and whatnot.

In the interests of keeping your managers tidy, you don't need the __init__ method either as it doesn't do anything that the default one wouldn't do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM