Changeset - 3b5b958b78b6
[Not reviewed]
0 2 0
Christopher Neugebauer - 8 years ago 2016-04-29 01:09:08
chrisjrn@gmail.com
Makes the discounts section from _handle_products evaluate lazily, just in case it’s never displayed in a template (those are some very very expensive queries there).
2 files changed with 35 insertions and 1 deletions:
0 comments (0 inline, 0 general)
registrasion/util.py
Show inline comments
 
import string
 

	
 
from django.utils.crypto import get_random_string
 

	
 

	
 
def generate_access_code():
 
    ''' Generates an access code for users' payments as well as their
 
    fulfilment code for check-in.
 
    The access code will 4 characters long, which allows for 1,500,625
 
    unique codes, which really should be enough for anyone. '''
 

	
 
    length = 4
 
    # all upper-case letters + digits 1-9 (no 0 vs O confusion)
 
    chars = string.uppercase + string.digits[1:]
 
    # 4 chars => 35 ** 4 = 1500625 (should be enough for anyone)
 
    return get_random_string(length=length, allowed_chars=chars)
 

	
 

	
 
def all_arguments_optional(ntcls):
 
    ''' Takes a namedtuple derivative and makes all of the arguments optional.
 
    '''
 

	
 
    ntcls.__new__.__defaults__ = (
 
        (None,) * len(ntcls._fields)
 
    )
 

	
 
    return ntcls
 

	
 

	
 
def lazy(function, *args, **kwargs):
 
    ''' Produces a callable so that functions can be lazily evaluated in
 
    templates.
 

	
 
    Arguments:
 

	
 
        function (callable): The function to call at evaluation time.
 

	
 
        args: Positional arguments, passed directly to ``function``.
 

	
 
        kwargs: Keyword arguments, passed directly to ``function``.
 

	
 
    Return:
 

	
 
        callable: A callable that will evaluate a call to ``function`` with
 
            the specified arguments.
 

	
 
    '''
 

	
 
    NOT_EVALUATED = object()
 
    retval = [NOT_EVALUATED]
 

	
 
    def evaluate():
 
        if retval[0] is NOT_EVALUATED:
 
            retval[0] = function(*args, **kwargs)
 
        return retval[0]
 

	
 
    return evaluate
registrasion/views.py
Show inline comments
...
 
@@ -384,97 +384,101 @@ def _handle_products(request, category, products, prefix):
 
    form instance, the discounts applicable to this form, and whether the
 
    contents were handled. '''
 

	
 
    current_cart = CartController.for_user(request.user)
 

	
 
    ProductsForm = forms.ProductsForm(category, products)
 

	
 
    # Create initial data for each of products in category
 
    items = commerce.ProductItem.objects.filter(
 
        product__in=products,
 
        cart=current_cart.cart,
 
    ).select_related("product")
 
    quantities = []
 
    seen = set()
 

	
 
    for item in items:
 
        quantities.append((item.product, item.quantity))
 
        seen.add(item.product)
 

	
 
    zeros = set(products) - seen
 
    for product in zeros:
 
        quantities.append((product, 0))
 

	
 
    products_form = ProductsForm(
 
        request.POST or None,
 
        product_quantities=quantities,
 
        prefix=prefix,
 
    )
 

	
 
    if request.method == "POST" and products_form.is_valid():
 
        if products_form.has_changed():
 
            _set_quantities_from_products_form(products_form, current_cart)
 

	
 
        # If category is required, the user must have at least one
 
        # in an active+valid cart
 
        if category.required:
 
            carts = commerce.Cart.objects.filter(user=request.user)
 
            items = commerce.ProductItem.objects.filter(
 
                product__category=category,
 
                cart=carts,
 
            )
 
            if len(items) == 0:
 
                products_form.add_error(
 
                    None,
 
                    "You must have at least one item from this category",
 
                )
 
    handled = False if products_form.errors else True
 

	
 
    discounts = DiscountController.available_discounts(
 
    # Making this a function to lazily evaluate when it's displayed
 
    # in templates.
 

	
 
    discounts = util.lazy(
 
        DiscountController.available_discounts,
 
        request.user,
 
        [],
 
        products,
 
    )
 

	
 
    return products_form, discounts, handled
 

	
 

	
 
def _set_quantities_from_products_form(products_form, current_cart):
 

	
 
    quantities = list(products_form.product_quantities())
 

	
 
    pks = [i[0] for i in quantities]
 
    products = inventory.Product.objects.filter(
 
        id__in=pks,
 
    ).select_related("category")
 

	
 
    product_quantities = [
 
        (products.get(pk=i[0]), i[1]) for i in quantities
 
    ]
 
    field_names = dict(
 
        (i[0][0], i[1][2]) for i in zip(product_quantities, quantities)
 
    )
 

	
 
    try:
 
        current_cart.set_quantities(product_quantities)
 
    except CartValidationError as ve:
 
        for ve_field in ve.error_list:
 
            product, message = ve_field.message
 
            if product in field_names:
 
                field = field_names[product]
 
            elif isinstance(product, inventory.Product):
 
                continue
 
            else:
 
                field = None
 
            products_form.add_error(field, message)
 

	
 

	
 
def _handle_voucher(request, prefix):
 
    ''' Handles a voucher form in the given request. Returns the voucher
 
    form instance, and whether the voucher code was handled. '''
 

	
 
    voucher_form = forms.VoucherForm(request.POST or None, prefix=prefix)
 
    current_cart = CartController.for_user(request.user)
 

	
 
    if (voucher_form.is_valid() and
 
            voucher_form.cleaned_data["voucher"].strip()):
 

	
0 comments (0 inline, 0 general)