mango
mango

Reputation: 553

How to render items based on checkbox boolean in app engine...aka checkbox hell

On the items for sale page, I display items with checkboxes next to them. If the user has checked one or more boxes and hit submit, I redirect to the cart page, where only the items that had their checkboxes checked are displayed.

Right now I'm modeling each item as such:

class SellModel(db.Model):
    user = db.ReferenceProperty(UserModel)
    amount = db.StringProperty(required = True)
    price = db.StringProperty(required = True)
    checked = db.BooleanProperty(default = False)

    def render(self):
        return render_str("sellmodel.html", s = self)

and the cart

class CartModel(db.Model):
    user = db.ReferenceProperty(UserModel)
    cart_amount = db.StringProperty(required = True)
    cart_price = db.StringProperty(required = True)

    def render(self):
        return render_str("cartmodel.html", c = self)

the post method of the sale page looks like this:

    first_name = self.request.get('first_name')
    last_name = self.request.get('last_name')
    email = self.request.get('email')

    sells = SellModel.all().ancestor(sell_key()).order('price')

    boxcount = 0
    for sell in sells:
        check = self.request.get('check')

        if check:
            #checkbox was checked, update checked attribute
            sell.checked = True
            sell.put()
            boxcount += 1

    if boxcount == 0:
        error = "check at least one box"
        self.render("buy.html", error = error, sells = sells)


    else: #user has checked 1+ boxes
        #check if user exists
        database = UserModel.all().filter("email =", email)

        count = 0
        for data in database:
            if data.email == email:
                count = 1
        #user doesn't exist
        if count == 0:
            user = UserModel(parent = user_key(),
                first_name = first_name, last_name = last_name, 
                email = email)
            user.put()
        #user exists
        else:
            #make key, get user from key
            u = UserModel.gql('where email = :email', email = email)
            user = u.get()   

            cart_items = SellModel.all().ancestor(sell_key()).filter('checked = ', True)

            #loop through checked items
            for item in cart_items:
                #commit item to cart_key
                cart_amount = item.amount
                cart_price = item.price
                cart = CartModel(parent = cart_key(), user = user, cart_amount = cart_amount, cart_price = cart_price)
                cart.put()

        self.redirect('/contact')  

the get method of the cart page:

cart = CartModel.all().ancestor(cart_key()).order('cart_price')
self.render("newbuy.html", cart = cart)

the cart page html:

{% for item in cart %}
    {{ item.render() | safe }}
{% endfor %}

the sale page html

<form method = "post">
<div class = "section1">
    <div class = "sellbox">
        <h1>current offers:</h1>
        {%if sells.count() == 0 %}
        <div>
            it looks like all the offers have been bought. check back later 
        </div>
        {%else%}
            <table>
                <tr class = "table_label">
                <th></th>
                <th>amount of mp</th>
                <th>price per mp</th>
                </tr>
                {% for sell in sells %}
                    {{ sell.render() | safe }}
                {% endfor %}
            </table>


            <p class="big">
                <label>first name</label>
                <input type="text" name="first_name" value="{{first_name}}">


                <label>last name</label>
                <input type="text" name="last_name" value="{{last_name}}">


                <label>email</label>
                <input type="text" name="email" value="{{email}}">
            </p>

            <div><input type="submit" value="review your order"></div>
            <div class="error">{{error}}</div> 
        {%endif%}
    </div>
</div>
</form>

sellmodel.html

<tr>
<td class = "checkbox">
    <input type = "checkbox" name = "check">
</td>

<td class = "entry_amount" name = "entry">
    {{s.amount}}
</td>

<td class = "entry_price" name = "entry">
    {{s.price}}
</td>
</tr>

The problem is no matter which boxes are checked, every single sales item is displayed on the cart page. When I look at the cartmodel in the datastore viewer, the checked attribute of every cartmodel instance is true/every single sellmodel instance was committed even though some had unchecked checkboxes. Why does the database think every item's checkbox was checked?

Upvotes: 0

Views: 1231

Answers (1)

Prahlad Yeri
Prahlad Yeri

Reputation: 3663

Change this line:

check = self.request.get('check')

to this:

if 'check' in self.request:
    check = True
else:
    check = False

The trouble is that the value returned by the get() method may or may not be converted to a boolean properly. And since the default behavior of browser is to post the checkbox value only if it is checked, the above code should work consistently.

Upvotes: 1

Related Questions