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

106

107

108

109

from decimal import Decimal 

from wtforms import TextField, DecimalField, SelectField, FileField 

from wtforms.validators import InputRequired, NumberRange, ValidationError 

from wtforms.widgets import html_params, Select, HTMLString 

from flask_wtf import Form 

from flask.ext.babel import lazy_gettext as _ 

from my_app import db 

 

 

class Product(db.Model): 

    id = db.Column(db.Integer, primary_key=True) 

    name = db.Column(db.String(255)) 

    price = db.Column(db.Float) 

    category_id = db.Column(db.Integer, db.ForeignKey('category.id')) 

    category = db.relationship( 

        'Category', backref=db.backref('products', lazy='dynamic') 

    ) 

    image_path = db.Column(db.String(255)) 

    user_timezone = db.Column(db.String(255)) 

 

    def __init__(self, name, price, category, image_path, user_timezone=''): 

        self.name = name 

        self.price = price 

        self.category = category 

        self.image_path = image_path 

        self.user_timezone = user_timezone 

 

    def __repr__(self): 

        return '<Product %d>' % self.id 

 

 

class Category(db.Model): 

    id = db.Column(db.Integer, primary_key=True) 

    name = db.Column(db.String(100)) 

 

    def __init__(self, name): 

        self.name = name 

 

    def __repr__(self): 

        return '<Category %d>' % self.id 

 

 

class NameForm(Form): 

    name = TextField(_('Name'), validators=[InputRequired()]) 

 

 

class CustomCategoryInput(Select): 

 

    def __call__(self, field, **kwargs): 

        kwargs.setdefault('id', field.id) 

        html = [] 

        for val, label, selected in field.iter_choices(): 

            html.append( 

                '<input type="radio" %s> %s' % ( 

                    html_params( 

                        name=field.name, value=val, checked=selected, **kwargs 

                    ), label 

                ) 

            ) 

        return HTMLString(' '.join(html)) 

 

 

class CategoryField(SelectField): 

    widget = CustomCategoryInput() 

 

    def iter_choices(self): 

        categories = [(c.id, c.name) for c in Category.query.all()] 

        for value, label in categories: 

            yield (value, label, self.coerce(value) == self.data) 

 

    def pre_validate(self, form): 

        for v, _ in [(c.id, c.name) for c in Category.query.all()]: 

            if self.data == v: 

                break 

        else: 

            raise ValueError(self.gettext('Not a valid choice')) 

 

 

class ProductForm(NameForm): 

    price = DecimalField(_('Price'), validators=[ 

        InputRequired(), NumberRange(min=Decimal('0.0')) 

    ]) 

    category = CategoryField( 

        _('Category'), validators=[InputRequired()], coerce=int 

    ) 

    image = FileField(_('Product Image')) 

 

 

def check_duplicate_category(case_sensitive=True): 

    def _check_duplicate(form, field): 

        if case_sensitive: 

            res = Category.query.filter( 

                Category.name.like('%' + field.data + '%') 

            ).first() 

        else: 

            res = Category.query.filter( 

                Category.name.ilike('%' + field.data + '%') 

            ).first() 

        if res: 

            raise ValidationError( 

                'Category named %s already exists' % field.data 

            ) 

    return _check_duplicate 

 

 

class CategoryForm(NameForm): 

    name = TextField(_('Name'), validators=[ 

        InputRequired(), check_duplicate_category() 

    ])