Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

"""Decorators for the django-shop application.""" 

from functools import wraps 

 

from django.contrib.auth import REDIRECT_FIELD_NAME 

from django.contrib.auth.decorators import user_passes_test 

from django.core.urlresolvers import reverse 

from django.http import HttpResponseRedirect 

from shop.util.cart import get_or_create_cart 

 

from shop.util.login_mixin import get_test_func 

from shop.util.order import get_order_from_request 

from shop.models.ordermodel import Order 

 

 

def on_method(function_decorator): 

    """ 

    Enables decorators for functions of classes (for example class based 

    views). 

 

    Credits go to: http://www.toddreed.name/content/django-view-class/ 

    """ 

    def decorate_method(unbound_method): 

        def method_proxy(self, *args, **kwargs): 

            def f(*a, **kw): 

                return unbound_method(self, *a, **kw) 

            return function_decorator(f)(*args, **kwargs) 

        return method_proxy 

    return decorate_method 

 

 

def shop_login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, 

                        login_url=None): 

    """ 

    Decorator for views that checks that the user is logged in, redirecting 

    to the log-in page if necessary. 

 

    Takes the `SHOP_FORCE_LOGIN` setting into consideration. 

    """ 

    actual_decorator = user_passes_test( 

        get_test_func(), 

        login_url=login_url, 

        redirect_field_name=redirect_field_name 

    ) 

46    if function: 

        return actual_decorator(function) 

    return actual_decorator 

 

def order_required(url_name='cart'): 

    """ 

    Ensures that an non-complete order exists before carrying out any 

    additional functions that rely on one. 

 

    If an order does not exist the browser will be redirected to another page 

    supplied in the optional keyword argument `url_name`. 

 

    Usage: 

    @order_required 

    def some_view(... 

 

    OR: 

    @order_required(url_name='cart') 

    def some_view(... 

    """ 

    if callable(url_name): 

        func = url_name 

        decorator = order_required() 

        return decorator(func) 

 

    def decorator(func): 

        def inner(request, *args, **kwargs): 

            order = get_order_from_request(request) 

            if order is None or getattr(order, 'status', Order.COMPLETED) >= Order.COMPLETED: 

                return HttpResponseRedirect(reverse(url_name)) 

            return func(request, *args, **kwargs) 

        return wraps(func)(inner) 

    return decorator 

 

def cart_required(url_name='cart'): 

    """ 

    Ensures that a non-empty cart is present. 

 

    If a cart does not exist the browser will be redirected to another page 

    supplied in the optional keyword argument `url_name`. 

 

    Usage: 

    @cart_required 

    def some_view(... 

 

    OR: 

    @cart_required(url_name='cart') 

    def some_view(... 

    """ 

    if callable(url_name): 

        func = url_name 

        decorator = cart_required() 

        return decorator(func) 

 

    def decorator(func): 

        def inner(request, *args, **kwargs): 

            cart = get_or_create_cart(request) 

            if cart.total_quantity <= 0: 

                return HttpResponseRedirect(reverse(url_name)) 

            return func(request, *args, **kwargs) 

        return wraps(func)(inner) 

    return decorator