Project Structure Of Online Shopping Cart Using Python(Django) -Part 2

Rashmi Mishra
0



Project Structure Of Online Shopping Cart

 Using Python(Django) 

online_shopping_cart/orders/__init__.py

"""

This is the initialization file for the orders app in the online shopping cart project.

The orders app handles functionality related to managing customer orders, including:

- Storing order details.

- Managing the association between users and their orders.

- Handling the status and payment of orders.

This app integrates with the Django ORM for data modeling and provides an interface for other parts of the application to interact with order-related data.

""" 

# You can include application-wide initialization code here if necessary.

# For example, you might import and configure signal handlers specific to this app.

 # Importing signals for order processing

from . import signals

 # Ensure the application is initialized correctly during Django startup.

default_app_config = 'online_shopping_cart.orders.apps.OrdersConfig'


 

 

Key Details:

1.   Purpose of __init__.py:

o    Marks the directory as a Python package.

o    Serves as an entry point for initializing the app-specific configurations.

2.   Documentation:

o    Includes a docstring explaining the purpose of the orders app and what it handles.

3.   Signals:

o    Demonstrates where you would import signals or other app-specific modules to ensure they are registered during application startup.

4.   Default App Configuration:

o    Explicitly sets default_app_config to reference the app configuration class (OrdersConfig) defined in apps.py. This ensures the app is initialized correctly when Django starts.

5.   Modular Design:

o    Keeps the file simple and only includes code that affects the initialization of the app. Additional logic (e.g., signals) is referenced but not directly implemented here.

online_shopping_cart/orders/admin.py

from django.contrib import admin

from .models import Order, OrderItem, Payment

class OrderItemInline(admin.TabularInline):

    """

    Inline admin for displaying order items directly within the order admin interface.

    """

    model = OrderItem

    extra = 0  # No extra blank forms by default

    readonly_fields = ('product', 'quantity', 'price', 'total_price')

    def total_price(self, obj):

        """

        Calculate the total price for an order item.

        """

        return obj.quantity * obj.price

    total_price.short_description = 'Total Price'

@admin.register(Order)

class OrderAdmin(admin.ModelAdmin):

    """

    Admin interface for managing orders.

    """

    list_display = ('id', 'user', 'status', 'created_at', 'updated_at')

    list_filter = ('status', 'created_at', 'updated_at')

    search_fields = ('user__username', 'id', 'status')

    readonly_fields = ('created_at', 'updated_at')

    inlines = [OrderItemInline]

    def view_on_site(self, obj):

        """

        Returns the URL to view the order on the site.

        """

        from django.urls import reverse

        return reverse('orders:order_detail', args=[obj.id])

@admin.register(Payment)

class PaymentAdmin(admin.ModelAdmin):

    """

    Admin interface for managing payments.

    """

    list_display = ('id', 'order', 'payment_method', 'amount', 'payment_status', 'created_at')

    list_filter = ('payment_status', 'payment_method', 'created_at')

    search_fields = ('order__id', 'payment_status', 'payment_method')

    readonly_fields = ('created_at', 'updated_at')

 

 Explanation:

1.   OrderItemInline:

o    Enables inline editing of OrderItem instances within the Order admin panel.

o    Adds a calculated total_price field to show the total price for each item.

2.   OrderAdmin:

o    Provides an admin interface for managing orders.

o    Displays relevant fields like id, user, status, and timestamps.

o    Filters orders by status and timestamps, making it easy to find specific orders.

o    Enables searching by user’s username or order ID.

o    Includes an inline for OrderItem so that order items can be managed directly from the order interface.

3.   view_on_site:

o    Returns the URL to view the order on the public-facing site.

4.   PaymentAdmin:

o    Provides an admin interface for managing payments.

o    Displays key payment details like order, payment_method, and payment_status.

o    Allows filtering and searching for payments based on payment method, status, or associated order ID.

5.   Best Practices:

o    Uses @admin.register decorators to register models with the admin site.

o    Implements readonly_fields for fields that shouldn’t be edited directly via the admin interface.

online_shopping_cart/orders/apps.py

from django.apps import AppConfig

class OrdersConfig(AppConfig):

    """

    Configuration class for the 'orders' app.

    """

    default_auto_field = 'django.db.models.BigAutoField'

    name = 'orders'

    verbose_name = 'Orders Management'


 

 Explanation:

1.   AppConfig Class:

o    Each app in a Django project has an associated configuration class that defines its settings.

o    OrdersConfig is the configuration class for the orders app.

2.   default_auto_field:

o    Specifies the type of auto-generated primary key fields for models in this app.

o    BigAutoField is used to handle larger datasets as it allows for bigger integer values.

3.   name:

o    Defines the Python import path for the app.

o    In this case, it's set to 'orders', which matches the directory structure.

4.   verbose_name:

o    Provides a human-readable name for the app.

o    This name will appear in the Django admin panel and other user-facing parts of the framework.

This file ensures the orders app is correctly registered and configured within the Django project.

online_shopping_cart/orders/models.py

It includes models for Order, OrderItem, and Payment.

from django.db import models

from django.conf import settings

from products.models import Product

class Order(models.Model):

    """

    Represents a customer's order.

    """

    STATUS_CHOICES = [

        ('pending', 'Pending'),

        ('confirmed', 'Confirmed'),

        ('shipped', 'Shipped'),

        ('delivered', 'Delivered'),

        ('cancelled', 'Cancelled'),

    ]

    user = models.ForeignKey(

        settings.AUTH_USER_MODEL,

        on_delete=models.CASCADE,

        related_name='orders'

    )

    created_at = models.DateTimeField(auto_now_add=True)

    updated_at = models.DateTimeField(auto_now=True)

    status = models.CharField(

        max_length=20,

        choices=STATUS_CHOICES,

        default='pending'

    )

    total_amount = models.DecimalField(

        max_digits=10,

        decimal_places=2,

        default=0.00

    )

    def __str__(self):

        return f"Order #{self.id} - {self.user.username}"

    def calculate_total(self):

        """

        Calculate and update the total amount of the order.

        """

        total = sum(item.total_price() for item in self.items.all())

        self.total_amount = total

        self.save()

class OrderItem(models.Model):

    """

    Represents a single item in an order.

    """

    order = models.ForeignKey(

        Order,

        on_delete=models.CASCADE,

        related_name='items'

    )

    product = models.ForeignKey(

        Product,

        on_delete=models.CASCADE

    )

    quantity = models.PositiveIntegerField()

    price = models.DecimalField(

        max_digits=10,

        decimal_places=2

    )

 

    def total_price(self):

        """

        Calculate the total price for this item.

        """

        return self.quantity * self.price

    def __str__(self):

        return f"{self.quantity} x {self.product.name}"

class Payment(models.Model):

    """

    Represents a payment for an order.

    """

    PAYMENT_METHOD_CHOICES = [

        ('credit_card', 'Credit Card'),

        ('paypal', 'PayPal'),

        ('cod', 'Cash on Delivery'),

    ]

    order = models.OneToOneField(

        Order,

        on_delete=models.CASCADE,

        related_name='payment'

    )

    method = models.CharField(

        max_length=20,

        choices=PAYMENT_METHOD_CHOICES

    )

    amount = models.DecimalField(

        max_digits=10,

        decimal_places=2

    )

    payment_date = models.DateTimeField(auto_now_add=True)

    transaction_id = models.CharField(

        max_length=100,

        blank=True,

        null=True

    )

    def __str__(self):

        return f"Payment for Order #{self.order.id} - {self.method}"

 

 Explanation:

1.   Order Model:

o    Stores general details about an order, such as the user who placed it, creation and update timestamps, status, and total amount.

o    The status field uses choices to restrict values to predefined statuses.

o    Includes a method calculate_total to compute the total order amount by summing up all its items.

2.   OrderItem Model:

o    Represents individual items within an order.

o    Links to the Order and Product models using ForeignKey.

o    Includes fields for quantity and price to calculate the total price for each item.

3.   Payment Model:

o    Manages payment details for an order.

o    Uses choices for the method field to restrict payment methods.

o    Includes fields for amount, payment_date, and transaction_id for tracking payments.

This structure supports handling orders, their items, and associated payments in the online shopping cart project.

online_shopping_cart/orders/views.py

This file includes views for creating an order, viewing order details, listing all orders for a user, and handling order status updates.


online_shopping_cart/orders/views.py

from django.shortcuts import render, get_object_or_404, redirect

from django.http import JsonResponse

from django.contrib.auth.decorators import login_required

from django.views.decorators.http import require_POST

from .models import Order, OrderItem

from products.models import Product

from .forms import OrderCreateForm

 

@login_required

def order_list(request):

    """

    Display a list of all orders for the logged-in user.

    """

    orders = Order.objects.filter(user=request.user).order_by('-created_at')

    context = {'orders': orders}

    return render(request, 'orders/order_list.html', context)

 

@login_required

def order_detail(request, order_id):

    """

    Display the details of a specific order.

    """

    order = get_object_or_404(Order, id=order_id, user=request.user)

    context = {'order': order}

    return render(request, 'orders/order_detail.html', context)

 

@login_required

@require_POST

def create_order(request):

    """

    Handle the creation of a new order.

    """

    cart = request.session.get('cart', {})

    if not cart:

        return redirect('products:product_list')

 

    order = Order.objects.create(user=request.user, status='pending')

   

    total_amount = 0

    for product_id, details in cart.items():

        product = get_object_or_404(Product, id=product_id)

        quantity = details['quantity']

        price = product.price

        total_amount += price * quantity

        OrderItem.objects.create(order=order, product=product, quantity=quantity, price=price)

   

    order.total_amount = total_amount

    order.save()

   

    # Clear cart after order creation

    request.session['cart'] = {}

    return redirect('orders:order_detail', order_id=order.id)

 

@login_required

@require_POST

def update_order_status(request, order_id):

    """

    Allow the user to update the status of their order.

    (For demonstration purposes, this could be limited to admins in a real-world app.)

    """

    order = get_object_or_404(Order, id=order_id, user=request.user)

    new_status = request.POST.get('status')

    if new_status in dict(Order.STATUS_CHOICES).keys():

        order.status = new_status

        order.save()

        return JsonResponse({'success': True, 'message': 'Order status updated successfully.'})

    return JsonResponse({'success': False, 'message': 'Invalid status update.'})


 

 

 Explanation:

1.   order_list View:

o    Displays all orders for the currently logged-in user.

o    Filters orders by the logged-in user's ID and orders them by creation date in descending order.

2.   order_detail View:

o    Fetches and displays details of a specific order.

o    Ensures only the owner of the order can access its details.

3.   create_order View:

o    Handles the creation of an order using items from the user's shopping cart stored in the session.

o    Iterates through the cart to create OrderItem instances and calculates the total order amount.

o    Clears the cart after the order is successfully created.

4.   update_order_status View:

o    Allows the logged-in user to update their order's status.

o    Validates the new status using the predefined STATUS_CHOICES.

o    Updates the status and returns a success or error message as a JSON response.

Notes:

  • The require_POST decorator ensures that certain views, like create_order and update_order_status, only accept POST requests for safety and data integrity.
  • A cart object is expected to be stored in the session, structured as a dictionary with product IDs as keys and quantities as values.
  • Error handling and permissions are implemented to ensure secure and user-specific access.

online_shopping_cart/orders/urls.py

It defines the URL patterns for accessing order-related views, such as listing orders, viewing order details, creating an order, and updating order status.


online_shopping_cart/orders/urls.py

from django.urls import path

from . import views

 

app_name = 'orders'

 

urlpatterns = [

    path('', views.order_list, name='order_list'),

    path('<int:order_id>/', views.order_detail, name='order_detail'),

    path('create/', views.create_order, name='create_order'),

    path('<int:order_id>/update-status/', views.update_order_status, name='update_order_status'),

]


 

 

Explanation:

1.   app_name:

o    This defines the namespace for the orders app, allowing you to reference these URLs specifically in templates and views using orders:<name>.

2.   urlpatterns:

o    path('', views.order_list, name='order_list'):

§  Maps the base URL of the orders app to the order_list view.

§  Displays a list of all orders for the logged-in user.

o    path('<int:order_id>/', views.order_detail, name='order_detail'):

§  Maps URLs containing an order ID to the order_detail view.

§  Displays detailed information about a specific order.

o    path('create/', views.create_order, name='create_order'):

§  Maps the /create/ URL to the create_order view.

§  Handles the creation of a new order from the shopping cart.

o    path('<int:order_id>/update-status/', views.update_order_status, name='update_order_status'):

§  Maps URLs containing an order ID and /update-status/ to the update_order_status view.

§  Handles updating the status of a specific order.


How to Use:

  • Include this urls.py in your project's main urls.py file using Django's include function:

from django.urls import path, include

urlpatterns = [

    path('orders/', include('orders.urls')),

]

This will make the orders app's URL patterns accessible under the /orders/ prefix.

Example URLs:

  • /orders/: List all orders.
  • /orders/1/: View details for the order with ID 1.
  • /orders/create/: Create a new order.
  • /orders/1/update-status/: Update the status of the order with ID 1.

online_shopping_cart/orders/templates/orders/order_history.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Order History</title>

    <link rel="stylesheet" href="{% static 'css/style.css' %}">

</head>

<body>

    <header>

        <h1>Order History</h1>

    </header>

    <main>

        {% if orders %}

            <table class="order-history-table">

                <thead>

                    <tr>

                        <th>Order ID</th>

                        <th>Date</th>

                        <th>Total Amount</th>

                        <th>Status</th>

                        <th>Details</th>

                    </tr>

                </thead>

                <tbody>

                    {% for order in orders %}

                        <tr>

                            <td>{{ order.id }}</td>

                            <td>{{ order.date|date:"F d, Y H:i" }}</td>

                            <td>${{ order.total_amount }}</td>

                            <td>{{ order.status }}</td>

                            <td>

                                <a href="{% url 'orders:order_detail' order.id %}">View Details</a>

                            </td>

                        </tr>

                    {% endfor %}

                </tbody>

            </table>

        {% else %}

            <p>You have no orders in your history.</p>

        {% endif %}

    </main>

    <footer>

        <p>&copy; {{ current_year }} Online Shopping Cart. All rights reserved.</p>

    </footer>

</body>

</html>


 

 

Explanation of Code:

1.   Header Section:

o    The <h1> tag introduces the page title: "Order History."

2.   Conditional Rendering:

o    {% if orders %}: Checks if the orders context variable contains any orders.

o    Displays the order history in a table if orders exist; otherwise, shows a message indicating no orders.

3.   Table Structure:

o    Headers:

§  Columns for Order ID, Date, Total Amount, Status, and Details.

o    Data Rows:

§  Loops through the orders context variable using {% for order in orders %}.

§  Each row displays the following:

§  Order ID: {{ order.id }}

§  Date: Formatted with date filter.

§  Total Amount: {{ order.total_amount }}

§  Status: {{ order.status }}

§  Details Link: Uses Django’s {% url %} tag to generate the URL for the order detail page.

4.   Fallback Message:

o    If no orders exist, the message "You have no orders in your history." is displayed.

5.   Footer Section:

o    Displays copyright information using the current_year variable.

6.   Styling:

o    External CSS (css/style.css) is included using Django’s {% static %} tag.


Context Variables Expected:

  • orders: A queryset of orders, where each order has attributes such as:
    • id: The order ID.
    • date: The order creation date.
    • total_amount: The total price for the order.
    • status: The status of the order (e.g., Pending, Shipped, Delivered).
  • current_year: The current year for display in the footer.

Example Rendered Output:

When Orders Exist:

Order ID

Date

Total Amount

Status

Details

1

September 25, 2024 14:30

$100.00

Shipped

View Details

2

September 20, 2024 10:15

$250.00

Delivered

View Details

When No Orders Exist:

  • "You have no orders in your history."


online_shopping_cart/orders/templates/orders/checkout.html

This template allows users to review their cart items, enter payment and shipping details, and confirm their purchase.


<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Checkout</title>

    <link rel="stylesheet" href="{% static 'css/style.css' %}">

</head>

<body>

    <header>

        <h1>Checkout</h1>

    </header>

    <main>

        <section class="cart-summary">

            <h2>Order Summary</h2>

            {% if cart_items %}

                <table class="cart-table">

                    <thead>

                        <tr>

                            <th>Product</th>

                            <th>Quantity</th>

                            <th>Price</th>

                            <th>Subtotal</th>

                        </tr>

                    </thead>

                    <tbody>

                        {% for item in cart_items %}

                            <tr>

                                <td>{{ item.product.name }}</td>

                                <td>{{ item.quantity }}</td>

                                <td>${{ item.product.price }}</td>

                                <td>${{ item.subtotal }}</td>

                            </tr>

                        {% endfor %}

                    </tbody>

                </table>

                <p class="total">Total: ${{ total }}</p>

            {% else %}

                <p>Your cart is empty. <a href="{% url 'products:product_list' %}">Continue Shopping</a></p>

            {% endif %}

        </section>

 

        <section class="checkout-form">

            <h2>Shipping and Payment Details</h2>

            <form method="post" action="{% url 'orders:checkout_process' %}">

                {% csrf_token %}

                <fieldset>

                    <legend>Shipping Information</legend>

                    <label for="name">Full Name:</label>

                    <input type="text" id="name" name="name" required>

 

                    <label for="address">Address:</label>

                    <textarea id="address" name="address" rows="3" required></textarea>

 

                    <label for="city">City:</label>

                    <input type="text" id="city" name="city" required>

 

                    <label for="postal_code">Postal Code:</label>

                    <input type="text" id="postal_code" name="postal_code" required>

 

                    <label for="phone">Phone Number:</label>

                    <input type="tel" id="phone" name="phone" required>

                </fieldset>

 

                <fieldset>

                    <legend>Payment Method</legend>

                    <label>

                        <input type="radio" name="payment_method" value="credit_card" required>

                        Credit Card

                    </label>

                    <label>

                        <input type="radio" name="payment_method" value="paypal" required>

                        PayPal

                    </label>

                    <label>

                        <input type="radio" name="payment_method" value="cash_on_delivery" required>

                        Cash on Delivery

                    </label>

                </fieldset>

 

                <button type="submit" class="btn-primary">Place Order</button>

            </form>

        </section>

    </main>

    <footer>

        <p>&copy; {{ current_year }} Online Shopping Cart. All rights reserved.</p>

    </footer>

</body>

</html>


 

 

 Explanation of Code:

1. Order Summary Section

  • Displays the list of cart items in a table format:
    • Product: Product name.
    • Quantity: Number of units for each product.
    • Price: Price per unit.
    • Subtotal: Quantity × Price for each item.
  • Includes the total amount at the bottom of the table: {{ total }}.
  • Provides a fallback message if the cart is empty.

2. Checkout Form

  • Contains two sections:
    • Shipping Information:
      • Full name, address, city, postal code, and phone number fields are included.
      • All fields are marked as required.
    • Payment Method:
      • Radio buttons allow users to select a payment method: Credit Card, PayPal, or Cash on Delivery.

3. CSRF Token

  • {% csrf_token %} ensures secure form submission.

4. Submit Button

  • Submits the form to the URL mapped to orders:checkout_process.

5. Footer

  • Displays the current year dynamically using the current_year variable.

Context Variables Expected:

  • cart_items: A list of cart items, where each item has:
    • product.name: Product name.
    • product.price: Product price.
    • quantity: Number of units.
    • subtotal: Calculated subtotal for the item.
  • total: The total cost of all items in the cart.
  • current_year: The current year for the footer.

Example Rendered Output:

Order Summary Example

Product

Quantity

Price

Subtotal

Laptop

1

$1000

$1000

Headphones

2

$50

$100

Total: $1100

Empty Cart Message

  • "Your cart is empty. Continue Shopping."

online_shopping_cart/orders/templates/orders/order_confirmation.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Order Confirmation</title>

    <link rel="stylesheet" href="{% static 'css/style.css' %}">

</head>

<body>

    <header>

        <h1>Order Confirmation</h1>

    </header>

    <main>

        <section class="confirmation-message">

            <h2>Thank You for Your Order!</h2>

            <p>Your order has been successfully placed. Below are your order details:</p>

        </section>

 

        <section class="order-details">

            <h2>Order Summary</h2>

            <p><strong>Order ID:</strong> {{ order.id }}</p>

            <p><strong>Order Date:</strong> {{ order.date }}</p>

 

            <h3>Shipping Information</h3>

            <p><strong>Name:</strong> {{ order.name }}</p>

            <p><strong>Address:</strong> {{ order.address }}</p>

            <p><strong>City:</strong> {{ order.city }}</p>

            <p><strong>Postal Code:</strong> {{ order.postal_code }}</p>

            <p><strong>Phone:</strong> {{ order.phone }}</p>

 

            <h3>Payment Information</h3>

            <p><strong>Payment Method:</strong> {{ order.payment_method }}</p>

 

            <h3>Items Purchased</h3>

            <table class="order-table">

                <thead>

                    <tr>

                        <th>Product</th>

                        <th>Quantity</th>

                        <th>Price</th>

                        <th>Subtotal</th>

                    </tr>

                </thead>

                <tbody>

                    {% for item in order.items %}

                        <tr>

                            <td>{{ item.product.name }}</td>

                            <td>{{ item.quantity }}</td>

                            <td>${{ item.product.price }}</td>

                            <td>${{ item.subtotal }}</td>

                        </tr>

                    {% endfor %}

                </tbody>

            </table>

            <p class="total"><strong>Total:</strong> ${{ order.total }}</p>

        </section>

 

        <section class="next-steps">

            <h2>What’s Next?</h2>

            <p>You will receive a confirmation email with the details of your order.</p>

            <p>If you have any questions, feel free to <a href="{% url 'contact_us' %}">contact us</a>.</p>

            <p><a href="{% url 'products:product_list' %}" class="btn-primary">Continue Shopping</a></p>

        </section>

    </main>

    <footer>

        <p>&copy; {{ current_year }} Online Shopping Cart. All rights reserved.</p>

    </footer>

</body>

</html>

 

 Explanation of Code:

1. Confirmation Message

  • Displays a friendly thank-you message to the user.

2. Order Details

  • Order ID: Displays the unique order ID: {{ order.id }}.
  • Order Date: Shows the date the order was placed: {{ order.date }}.
  • Shipping Information: Includes name, address, city, postal code, and phone.
  • Payment Information: Displays the selected payment method: {{ order.payment_method }}.

3. Items Purchased

  • A table displays the details of the purchased items:
    • Product Name.
    • Quantity.
    • Price per Unit.
    • Subtotal (calculated as quantity × price).
  • Total Amount: Displays the total price for all items in the order.

4. Next Steps

  • Suggests the user will receive a confirmation email.
  • Includes a link to contact support and a button to continue shopping.

Context Variables Expected:

  • order: The order object containing:
    • id: Unique order ID.
    • date: Date of the order.
    • name, address, city, postal_code, phone: Shipping details.
    • payment_method: Selected payment method.
    • items: List of items in the order. Each item includes:
      • product.name: Name of the product.
      • product.price: Price of the product.
      • quantity: Quantity purchased.
      • subtotal: Subtotal for the item.
    • total: Total cost of the order.
  • current_year: The current year for the footer.

Example Rendered Output:

Order Summary Example

  • Order ID: 12345
  • Order Date: 2024-12-25

Shipping Information

  • Name: John Doe
  • Address: 123 Elm Street
  • City: Springfield
  • Postal Code: 12345
  • Phone: 9876543210

Payment Information

  • Payment Method: Credit Card

Items Purchased

Product

Quantity

Price

Subtotal

Laptop

1

$1000

$1000

Headphones

2

$50

$100

Total: $1100


online_shopping_cart/orders/__init__.py

"""

This package handles all operations related to orders within the online shopping cart project.

It includes models, views, and templates for managing orders, including order placement,

checkout, history, and confirmation.

 

Modules:

- admin.py: Admin interface for managing orders.

- apps.py: App configuration for the orders application.

- models.py: Database models for orders and related entities.

- views.py: Logic for handling order-related requests.

- urls.py: URL routing for order views.

 

Templates:

- order_history.html: Displays the order history for a user.

- checkout.html: Handles the checkout process for the user.

- order_confirmation.html: Shows the confirmation details after an order is placed.

"""

 

# The __init__.py file is used to mark this directory as a Python package.

# It can also be used for package-level imports if needed.


 

 Purpose:

  • Marks the orders directory as a Python package.
  • Provides a description of the package's purpose and its components.

online_shopping_cart/static/css/main.css

/* Global Reset and Base Styles */

/* Reset some default browser styling */

* {

    margin: 0;

    padding: 0;

    box-sizing: border-box;

}

 

/* Set a default font family */

body {

    font-family: 'Arial', sans-serif;

    line-height: 1.6;

    background-color: #f4f4f4;

    color: #333;

}

 

/* Define the body padding and max-width */

.container {

    width: 90%;

    margin: 0 auto;

    max-width: 1200px;

}

/* Header Styles */

header {

    background-color: #333;

    color: #fff;

    padding: 10px 0;

    text-align: center;

}

header h1 {

    font-size: 2.5rem;

    margin-bottom: 10px;

}

header nav {

    margin-top: 10px;

}

header nav ul {

    list-style: none;

    display: flex;

    justify-content: center;

}

header nav ul li {

    margin: 0 15px;

}

 

header nav ul li a {

    color: #fff;

    text-decoration: none;

    font-size: 1.2rem;

    padding: 5px 10px;

    transition: background-color 0.3s;

}

 

header nav ul li a:hover {

    background-color: #555;

    border-radius: 5px;

}

 

/* Product Listing Styles */

.product-list {

    display: grid;

    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));

    gap: 30px;

    margin-top: 30px;

}

 

.product-item {

    background-color: #fff;

    border: 1px solid #ddd;

    padding: 20px;

    border-radius: 8px;

    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

    transition: transform 0.3s ease;

}

 

.product-item:hover {

    transform: translateY(-5px);

}

 

.product-item img {

    width: 100%;

    height: auto;

    border-radius: 8px;

}

 

.product-item h3 {

    font-size: 1.6rem;

    margin-top: 15px;

}

 

.product-item p {

    font-size: 1rem;

    color: #555;

}

 

.product-item .price {

    font-size: 1.4rem;

    color: #007bff;

    font-weight: bold;

    margin-top: 10px;

}

 

.product-item .btn-add-to-cart {

    background-color: #28a745;

    color: #fff;

    border: none;

    padding: 10px 15px;

    font-size: 1.1rem;

    cursor: pointer;

    border-radius: 5px;

    transition: background-color 0.3s;

}

 

.product-item .btn-add-to-cart:hover {

    background-color: #218838;

}

 

/* Cart and Checkout Styles */

.cart-container, .checkout-container {

    background-color: #fff;

    padding: 20px;

    margin-top: 30px;

    border-radius: 8px;

    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

}

 

.cart-container table, .checkout-container table {

    width: 100%;

    border-collapse: collapse;

    margin-bottom: 20px;

}

 

.cart-container th, .checkout-container th,

.cart-container td, .checkout-container td {

    padding: 10px;

    text-align: left;

    border-bottom: 1px solid #ddd;

}

 

.cart-container th, .checkout-container th {

    background-color: #f7f7f7;

}

 

.cart-container .total, .checkout-container .total {

    font-size: 1.4rem;

    font-weight: bold;

    color: #333;

    text-align: right;

}

 

.btn-checkout {

    background-color: #007bff;

    color: #fff;

    border: none;

    padding: 12px 20px;

    font-size: 1.2rem;

    cursor: pointer;

    border-radius: 5px;

    transition: background-color 0.3s;

}

 

.btn-checkout:hover {

    background-color: #0056b3;

}

 

/* Footer Styles */

footer {

    background-color: #333;

    color: #fff;

    text-align: center;

    padding: 15px;

    margin-top: 50px;

}

 

footer p {

    font-size: 1rem;

}

 

/* User Account Styles */

.user-profile {

    background-color: #fff;

    padding: 20px;

    margin-top: 30px;

    border-radius: 8px;

    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

}

 

.user-profile h2 {

    font-size: 2rem;

    margin-bottom: 20px;

}

 

.user-profile .user-info {

    font-size: 1.2rem;

    margin-bottom: 10px;

}

 

/* Media Queries for Responsiveness */

@media screen and (max-width: 768px) {

    header h1 {

        font-size: 2rem;

    }

 

    .product-list {

        grid-template-columns: 1fr 1fr;

    }

 

    .product-item h3 {

        font-size: 1.4rem;

    }

 

    .product-item p {

        font-size: 0.9rem;

    }

 

    .cart-container table, .checkout-container table {

        font-size: 0.9rem;

    }

 

    .btn-add-to-cart {

        font-size: 1rem;

    }

 

    .btn-checkout {

        font-size: 1.1rem;

    }

}

 

 Explanation of the Styles:

1.   Global Reset and Base Styles:

o    The * selector resets the margin and padding for all elements to eliminate browser inconsistencies.

o    The body tag sets the base font and background for the entire project.

o    A .container class is defined for setting the main content width and centering it.

2.   Header Styles:

o    The header class styles the navigation bar and the site title.

o    The navigation menu (nav ul) is displayed as a flex container, allowing for horizontally aligned links.

3.   Product Listing:

o    The .product-list class displays products in a responsive grid, automatically adjusting the number of columns based on screen size.

o    Each .product-item includes an image, product title, description, and price, with hover effects for interactivity.

4.   Cart and Checkout Styles:

o    Both cart and checkout containers have a white background, padding, and border-radius for styling.

o    Tables within these containers are styled for readability and a clean layout.

5.   Footer Styles:

o    The footer provides a basic footer with centered text, matching the site's color scheme.

6.   User Account Styles:

o    The .user-profile class is used for the user profile page, with a clean and professional layout.

7.   Media Queries:

o    These are used to make the layout responsive, adjusting the number of columns in the product list and font sizes when the screen width is below 768px.

Next Steps:

  • You can customize the colors, fonts, and layout further based on your brand's style.
  • Consider adding more specific styling for different elements, like buttons, form inputs, or modals.

online_shopping_cart/templates/base.html

The base.html file serves as the foundation layout template that other templates (like product listings, checkout, etc.) will extend.

online_shopping_cart/templates/base.html

<!DOCTYPE html>

<html lang="en">

 

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>{% block title %}Online Shopping Cart{% endblock %}</title>

 

    <!-- Link to CSS file -->

    <link rel="stylesheet" href="{% static 'css/main.css' %}">

 

    <!-- Add any additional CSS or JavaScript here -->

    {% block extra_head %}

    {% endblock %}

</head>

 

<body>

 

    <!-- Header Section -->

    <header>

        <div class="container">

            <h1><a href="{% url 'home' %}">Online Shopping Cart</a></h1>

 

            <nav>

                <ul>

                    <li><a href="{% url 'home' %}">Home</a></li>

                    <li><a href="{% url 'product_list' %}">Products</a></li>

                    {% if user.is_authenticated %}

                        <li><a href="{% url 'profile' %}">Profile</a></li>

                        <li><a href="{% url 'logout' %}">Logout</a></li>

                    {% else %}

                        <li><a href="{% url 'login' %}">Login</a></li>

                        <li><a href="{% url 'register' %}">Register</a></li>

                    {% endif %}

                    <li><a href="{% url 'cart' %}">Cart ({{ cart_item_count }})</a></li>

                </ul>

            </nav>

        </div>

    </header>

 

    <!-- Main Content Section -->

    <main class="container">

        {% block content %}

        {% endblock %}

    </main>

 

    <!-- Footer Section -->

    <footer>

        <p>&copy; 2024 Online Shopping Cart. All rights reserved.</p>

    </footer>

 

    <!-- JavaScript Files -->

    <script src="{% static 'js/cart.js' %}"></script>

    {% block extra_js %}

    {% endblock %}

</body>

 

</html>

 

 Explanation of the Template:

1.   HTML Doctype and Meta Tags:

o    The template begins with the <!DOCTYPE html> declaration, followed by standard HTML meta tags for character set, viewport settings, and browser compatibility.

2.   Block for Title:

o    The {% block title %} is a placeholder for the title of each individual page that extends this base template. For example, product listings could use a title like "Product List" while the cart page would use "Shopping Cart".

3.   CSS and JS Includes:

o    The main CSS file (main.css) is linked in the <head> section using {% static 'css/main.css' %} to reference the static file.

o    There’s also an {% block extra_head %} placeholder, where you can add custom CSS or meta tags for specific pages that extend this template.

o    The cart.js script is included at the end of the body to ensure the page content loads first. The {% block extra_js %} allows for additional JS files or scripts to be added per page.

4.   Header Section:

o    This section contains the site title (which links to the home page) and the navigation menu. The menu links to pages like home, products, login, registration, profile, and cart.

o    The {% if user.is_authenticated %} checks if the user is logged in. If logged in, it displays profile and logout links; otherwise, it shows login and register links.

o    The cart item count is dynamically displayed using the cart_item_count context variable, which should be passed from views to this template.

5.   Main Content Section:

o    The {% block content %} is a placeholder for the main content of each page. This will be replaced by the content from the page that extends base.html.

6.   Footer Section:

o    A basic footer with the copyright information is included at the bottom of the page.

Customization:

  • Dynamic Title: The title of each page can be customized by overriding the {% block title %} in child templates (e.g., product_list.html).
  • JavaScript: If specific JavaScript is required for a page (like for form validation or handling the cart), it can be added using the {% block extra_js %} in the child templates.

Example of a Child Template Extending base.html:

Here’s a quick example of how a child template for the product list page (product_list.html) would look:

html

Copy code

{% extends 'base.html' %}

 

{% block title %}Product List{% endblock %}

 

{% block content %}

    <h2>Available Products</h2>

    <div class="product-list">

        {% for product in products %}

            <div class="product-item">

                <img src="{{ product.image_url }}" alt="{{ product.name }}">

                <h3>{{ product.name }}</h3>

                <p>{{ product.description }}</p>

                <div class="price">${{ product.price }}</div>

                <form method="post" action="{% url 'add_to_cart' product.id %}">

                    {% csrf_token %}

                    <button type="submit" class="btn-add-to-cart">Add to Cart</button>

                </form>

            </div>

        {% endfor %}

    </div>

{% endblock %}

Key Features:

  • Inheritance: The page inherits the layout and structure defined in base.html using {% extends 'base.html' %}.
  • Title Customization: The title block is overridden to display "Product List" for this page.
  • Product Display: The page dynamically renders products in a grid layout, with each product displaying its image, name, description, and price.

This base.html file allows you to maintain a consistent look and feel across your entire website while enabling child templates to define their unique content.

 

Post a Comment

0Comments

Post a Comment (0)