pythondjangomodele-commerce

Django - Python: 'int' object has no attribute 'get'


I am setting up a Django project to allow tickets to be sold for various theatre dates with a price for adults and a price for children. I have created a models.py and ticket_details.html.

I am unfortunately receiving the following error: 'int' object has no attribute 'get' and I am at a loss to how I am to get the adult and child price for the total calculations to display in my bag.html.

The problem is with my contexts.py and views.py files. I have tried the 'get' option but it is not working. Can someone advise?

enter image description here

models.py:

class Show(models.Model):

    '''Programmatic Name'''
    name = models.CharField(max_length=254)
    friendly_name = models.CharField(max_length=254, null=True, blank=True)
    poster = models.ImageField(null=True, blank=True)

    def __str__(self):
        return self.name

    def get_friendly_name(self):
        return self.friendly_name


class Ticket(models.Model):

    show = models.ForeignKey('show', null=True, blank=True, on_delete=models.SET_NULL)
    name = models.CharField(max_length=254)
    event_date = models.CharField(max_length=254)
    description = models.TextField(null=True, blank=True)
    event_details = models.TextField(null=True, blank=True)
    place = models.CharField(max_length=254)
    location = models.CharField(max_length=254)
    position = models.CharField(max_length=254)
    image = models.ImageField(null=True, blank=True)
    price_details = models.TextField(null=True, blank=True)
    date = models.DateTimeField(null=True, blank=True)
    adult_price = models.DecimalField(max_digits=8, decimal_places=2, null=True, blank=True)
    child_price = models.DecimalField(max_digits=8, decimal_places=2, null=True, blank=True)

    def __str__(self):
        return self.name

ticket_detail.html:

<form class="form" action="{% url 'add_to_bag' ticket.id %}" method="POST">
                {% csrf_token %}
                <div class="form-row">
                    <div class="form-group w-50">
                        <div class="input-group">
                            <div class="input-group-prepend">
                                <button class="decrement-qty btn btn-black rounded-0" data-item_id="{{ ticket.id }}"
                                    id="decrement-qty_{{ ticket.id }}">
                                    <span class="icon">
                                        <i class="fas fa-minus"></i>
                                    </span>
                                </button>
                            </div>
                            <input class="form-control qty_input" type="number" name="adult_quantity" value="1" min="1"
                                max="99" data-item_id="{{ ticket.id }}" id="adult_ticket">
                            <div class="input-group-append">
                                <button class="increment-qty btn btn-black rounded-0" data-item_id="{{ ticket.id }}"
                                    id="increment-qty_{{ ticket.id }}">
                                    <span class="icon">
                                        <i class="fas fa-plus"></i>
                                    </span>
                                </button>
                            </div>
                        </div>
                        <div class="input-group">
                            <div class="input-group-prepend">
                                <button class="decrement-qty btn btn-black rounded-0" data-item_id="{{ ticket.id }}"
                                    id="decrement-qty_{{ ticket.id }}">
                                    <span class="icon">
                                        <i class="fas fa-minus"></i>
                                    </span>
                                </button>
                            </div>
                            <input class="form-control qty_input" type="number" name="child_quantity" value="1" min="1"
                                max="99" data-item_id="{{ ticket.id }}" id="child_ticket">
                            <div class="input-group-append">
                                <button class="increment-qty btn btn-black rounded-0" data-item_id="{{ ticket.id }}"
                                    id="increment-qty_{{ ticket.id }}">
                                    <span class="icon">
                                        <i class="fas fa-plus"></i>
                                    </span>
                                </button>
                            </div>
                        </div>
                    </div>
                    <div class="col-12 mb-3">
                        <input type="submit" class="btn btn-default btn-lg text-uppercase pl-5 pr-5"
                            value="Add to Bag" />
                    </div>
                    <input type="hidden" name="redirect_url" value="{{ request.path }}" />
                </div>
            </form>

I have created an app for 'bag' as well as a views.py and contexts.py accordingly.

bag.html

<div class="col-12">
            {% if bag_items %}
            <div class="table-responsive rounded">
                <table class="table content-p">
                    <tr>
                        <th scope="col">Ticket Info</th>
                        <th scope="col">Date</th>
                        <th scope="col">Price</th>
                        <th scope="col">Quantity</th>
                        <th scope="col">Sub Total</th>
                    </tr>
                    {% for item in bag_items %}
                    {% if item.adult_ticket %}
                    <tr>
                        <td>{{ item.ticket.name }}</td>
                        <td>{{ item.ticket.date}}</td>
                        <td>{{ item.ticket.adult_price }}</td>
                        <td>
                            <form class="form update-form" method="POST" action="{% url 'adjust_bag' item.item_id %}">
                                {% csrf_token %}
                                <div class="form-group">
                                    <div class="input-group">
                                        <div class="input-group-prepend">
                                            <button class="decrement-qty btn btn-sm btn-black rounded-0"
                                                data-item_id="{{ item.item_id }}" id="decrement-qty_{{ item.item_id }}">
                                                <span>
                                                    <i class="fas fa-minus fa-sm"></i>
                                                </span>
                                            </button>
                                        </div>
                                        <input class="form-control form-control-sm qty_input" type="number"
                                            id="adult-ticket" name="adultquantity" value="{{ item.quantity }}" min="1"
                                            max="99" data-item_id="{{ item.item_id }}" id="id_qty_{{ item.item_id }}">
                                        <div class="input-group-append">
                                            <button class="increment-qty btn btn-sm btn-black rounded-0"
                                                data-item_id="{{ item.item_id }}" id="increment-qty_{{ item.item_id }}">
                                                <span>
                                                    <i class="fas fa-plus fa-sm"></i>
                                                </span>
                                            </button>
                                        </div>
                                    </div>
                                </div>
                            </form>
                            <a class="update-link text-info"><small>Update</small></a>
                            <a class="remove-item text-danger float-right" id="remove_{{ item.item_id }}"
                                data-product_size="{{ item.size }}"><small>Remove</small></a>
                        </td>
                        <td>${{ item.ticket.price|calc_subtotal:item.adult_quantity }}</td>
                    </tr>
                    {% elif item.child_ticket %}
                    <tr>
                        <td>{{ item.ticket.name }}</td>
                        <td>{{ item.ticket.date}}</td>
                        <td>{{ item.ticket.child_price }}</td>
                        <td>
                            <form class="form update-form" method="POST" action="{% url 'adjust_bag' item.item_id %}">
                                {% csrf_token %}
                                <div class="form-group">
                                    <div class="input-group">
                                        <div class="input-group-prepend">
                                            <button class="decrement-qty btn btn-sm btn-black rounded-0"
                                                data-item_id="{{ item.item_id }}" id="decrement-qty_{{ item.item_id }}">
                                                <span>
                                                    <i class="fas fa-minus fa-sm"></i>
                                                </span>
                                            </button>
                                        </div>
                                        <input class="form-control form-control-sm qty_input" type="number"
                                            id="child-ticket" name="child_quantity" value="{{ item.quantity }}" min="1"
                                            max="99" data-item_id="{{ item.item_id }}" id="id_qty_{{ item.item_id }}">
                                        <div class="input-group-append">
                                            <button class="increment-qty btn btn-sm btn-black rounded-0"
                                                data-item_id="{{ item.item_id }}" id="increment-qty_{{ item.item_id }}">
                                                <span>
                                                    <i class="fas fa-plus fa-sm"></i>
                                                </span>
                                            </button>
                                        </div>
                                    </div>
                                </div>
                            </form>
                            <a class="update-link text-info"><small>Update</small></a>
                            <a class="remove-item text-danger float-right" id="remove_{{ item.item_id }}"
                                data-product_size="{{ item.size }}"><small>Remove</small></a>
                        </td>
                        <td>${{ item.ticket.price|calc_subtotal:item.child_quantity }}</td>
                    </tr>
                    {% endif %}
                    {% endfor %}
                    <tr>
                        <td>Bag Total: €{{ grand_total|floatformat:2 }}</td>
                    </tr>
                </table>
            </div>
            {% else %}
            <p>Your bag is empty</p>
            {% endif %}
        </div>

views.py

def add_to_bag(request, item_id):
    '''Submit form to this view including ticket id and quanity'''
    ''' Add a quantity of the specified tickets to the shopping bag'''

    child_quantity = int(request.POST.get('child_quantity'))
    adult_quantity = int(request.POST.get('adult_quantity'))
    redirect_url = request.POST.get('redirect_url')
    bag = request.session.get('bag', {})
    '''Once in view get bag variable if exisits in session or create if doesnt'''

    '''Add to bag'''

    def add_quantity(quantity, item_id, bag):
        if quantity:
            if item_id in list(bag.keys()):
                bag[item_id] += quantity
            else:
                bag[item_id] = quantity

    if adult_quantity or child_quantity:

        if adult_quantity:
            add_quantity(
                adult_quantity,
                'adult_quantity',
                item_id,
                bag,)

        if child_quantity:
            add_quantity(
                child_quantity,
                'child_quantity',
                item_id,
                bag,)

    request.session['bag'] = bag
    return redirect(redirect_url)

contexts.py

from django.conf import settings
from django.shortcuts import get_object_or_404
from tickets.models import Ticket


def bag_contents(request):

    bag_items = []
    '''Empty list for bag items to live in'''
    total = 0
    ticket_count = 0
    bag = request.session.get('bag', {})

    for item_id, adult_quantity in bag.items():
        if adult_quantity.get('adult_quantity'):
            ticket = get_object_or_404(Ticket, pk=item_id)
            total += adult_quantity.get('adult_quantity') * ticket.adult_price
            ticket_count += adult_quantity.get('adult_quantity')
            bag_items.append({
                'item_id': item_id,
                'quantity': adult_quantity.get('adult_quantity'),
                'ticket': ticket,
                'adult_ticket': True,
            })

    for item_id, child_quantity in bag.items():
        if child_quantity.get('child_quantity'):
            ticket = get_object_or_404(Ticket, pk=item_id)
            total += child_quantity.get('child_quantity') * ticket.child_price
            ticket_count += child_quantity.get('child_quantity')
            bag_items.append({
                'item_id': item_id,
                'quantity': child_quantity.get('child_quantity'),
                'ticket': ticket,
                'child_ticket': True,
            })

    grand_total = total

    context = {
        'bag_items': bag_items,
        'total': total,
        'ticket_count': ticket_count,
        'grand_total': grand_total,
    }

    '''Make dictionary available to all templates across the enitire application'''
    return context

Solution

  • The issue is how you are iterating in for item_id, adult_quantity in bag.items():. I see that bag is a dictionary, and I think that it's a dictionary like:

    {
        'item_id': 1,
        'quantity': 10,
        'ticket': ticket,
        'adult_ticket': True,
    }
    

    If this is correct, then why do you need to iterate through a bag in contexts.py? Would this not work:

    def bag_contents(request):
    
        bag_items = []
        '''Empty list for bag items to live in'''
        total = 0
        ticket_count = 0
        bag = request.session.get('bag', {})
    
        if 'item_id' in bag:
            item_id = bag.item_id
        else:
            item_id = None
            
        ticket = get_object_or_404(Ticket, pk=item_id)
    
        if bag.adult_ticket:
            total += bag.quantity * ticket.adult_price
            bag_items.append({
                'item_id': item_id,
                'quantity': bag.quantity,
                'ticket': ticket,
                'adult_ticket': True,
            })
        if bag.child_ticket:
            total += bag.quantity * ticket.child_price
            bag_items.append({
                'item_id': item_id,
                'quantity': bag.quantity,
                'ticket': ticket,
                'child_ticket': True,
            })
            
        ticket_count += bag.quantity
    
    
        grand_total = total
    
        context = {
            'bag_items': bag_items,
            'total': total,
            'ticket_count': ticket_count,
            'grand_total': grand_total,
        }
    
        '''Make dictionary available to all templates across the enitire application'''
        return context