Monday, February 10, 2014

Re: I'm getting obsessed! Where should I put this code?

A common function that can get called from multiple places may be the way to go.  For example (please adapt!):

#view file
# try allocate some stock to product
try:
    instance.stock = get_stock(availability="Available", product=product):
    instance.stock.allocate()
except:
    pass  # do something else?

#common file
from foobar.models import Stock

def get_stock(availability, product, caller='view'):
    """Return stock, if available, else raise an error."""
    try:
        stock = Stock.objects.filter(availability=availability, product=product)[:1].get()
        return stock
    except Stock.DoesNotExist:
        if not caller or caller == 'view':
            raise CustomBadRequest(
                code="stock",
                message="No stock left"
            )
            return None
        elif caller == 'other':
            raise CustomBadError(
                code="stock",
                message="Stock is all gone"
            )
            return None
        else:
            pass
    finally:
        return None

On Monday, 10 February 2014 04:48:05 UTC+2, Nikolas Stevenson-Molnar wrote:
I'm not sure it makes sense to put something that raises a "BadRequest" type error in the model. That's more of an API exception. I'd say put it in the resource. If you find yourself repeating it a lot then put the validation in it's own function and/or use subclasses if appropriate.

_Nik

On 2/9/2014 10:18 AM, Arnold Krille wrote:
> On Sun, 9 Feb 2014 02:15:46 -0800 (PST) Glyn Jackson
> <...@glynjackson.org> wrote:
>> So far I have moved this logic around so many times, but where should
>> it really be happening in my Django project? Opinions very much
>> welcome. Thanks
>>
>> 1) product  *pre_save* - this works really well but validation looks
>> odd here!
>> 2) product  *model save()* - again validation looks odd here!
>> 3) product *model manager *- this seems bad as I'm referencing the
>> stock model in product manager.
>> 4) *views* - I end up repeating the save validation and code looks
>> really bad, also I have to do it again for API and normal views
>> 5) *tastypie recourse* - just as bad as views I think.
>
> Model! If its validation and 'save' should stop if there is none in
> stock, its either a pre-save-trigger or on your own save-method before
> calling super(...).save(). Be aware that if you subclass your product,
> a pre-save trigger has to get connected to all derived classes too, so
> it might be easier to just add it to the save-method.
>
> The advantage is clearly that the same code is used for all views. And
> api-resources are a view too (or a controller but lets not discuss
> thie here).
>
> - Arnold



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/9dd6d096-d6b1-4ef7-a59f-a80c40d3444f%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments:

Post a Comment