STAY INFORMED
following content serves as a personal note and may lack complete accuracy or
certainty.
Minimal-Mistakes instruction
Useful vscode Shortcut Keys
Unix Commands
npm Commands
Vim Commands
Git Note
Useful Figma Shortcut Keys
E-Commerce Website Project_3
E-Commerce Website Project_1 E-Commerce Website Project_2 E-Commerce Website Project_4 E-Commerce Website Project_5
Views
Item List View
# views.py
from .models import Item
def item_list(request):
items = Item.objects.all()
context = {"items": items}
return render(request, "ecommerce/item_list.html", context)
<!-- item_list.html -->
{% extends "ecommerce_base/base.html" %}
{% block content %}
<h1>item list</h1>
{% for item in items %}
<a href="{% url 'item-detail' item.id %}"><p>{{item.name}} detail</p></a>
{% endfor %}
{% endblock content %}
Item Detail View
url pattern be like
# urls.py
urlpatterns = [
path("", views.index, name='index'),
path("items/", views.item_list, name='item-list'),
path("items/<int:item_id>/", views.item_detail, name='item-detail'),
path("profile/", views.user_profile, name='user-profile'),
]
Because to display one specific item, need item’s id. Also each item has reviews, so import Review model and get reviews depending on the item_id.
# views.py
def item_detail(request, item_id):
item = Item.objects.get(id=item_id)
reviews = Review.objects.filter(item=item)
context = {"item": item,
"reviews": reviews
}
return render(request, "ecommerce/item_detail.html", context)
the ‘item_id’ parameter is used for “
<!-- item_detail.html -->
{% extends "ecommerce_base/base.html" %}
{% block content %}
<h1>{{item.name}}</h1>
<h1>{{item.category}}</h1>
<img src="{{item.image.url}}" alt="itemImg">
{% if reviews %}
<ul>
{% for review in reviews %}
<li>
<strong>Rate:</strong> {{ review.rate }}<br>
<strong>Comment:</strong> {{ review.comment }}<br>
<strong>Date:</strong> {{ review.createdAt }}
</li>
{% endfor %}
</ul>
{% else %}
<p>No reviews available for this item.</p>
{% endif %}
{% endblock content %}
Profile View
For now, I will make profile page displays logged in user’s infos and design it later.
# views.py
def user_profile(request, user_id):
user = get_object_or_404(User, id=user_id)
reviews = Review.objects.filter(user=user)
orders = Order.objects.filter(user=user)
context = {
'user': user,
'reviews': reviews,
"orders": orders
}
return render(request, "ecommerce/user_profile.html", context)
Cart View
Before create cart view, need add to cart function.
# views.py
def add_to_cart(request, item_id):
# Get or create a cart for the user
cart, created = Cart.objects.get_or_create(user=request.user)
# Get the item to be added to the cart
item = get_object_or_404(Item, id=item_id)
# Check if the item is already in the cart
cart_item, created = CartItem.objects.get_or_create(
item=item,
cart=cart,
defaults={'quantity': 1, 'price': item.price}
)
if not created:
# If the item already exists in the cart, update the quantity
cart_item.quantity += 1
cart_item.save()
return redirect('item-list') # Redirect to wherever you want after adding to the cart
def cart_list(request):
cart, created = Cart.objects.get_or_create(user=request.user)
cart_items = CartItem.objects.filter(cart=cart)
context = {
"cart": cart,
"cart_items": cart_items
}
return render(request, "ecommerce/cart.html", context)
Forms
Review Form
First, create a review form class.
# forms.py
class ReviewForm(forms.ModelForm):
class Meta:
model = Review
fields = '__all__'
# views.py
def create_review(request, item_id):
item = Item.objects.get(id=item_id)
review_form = ReviewForm()
if request.method == 'POST':
rate = request.POST.get('rate')
comment = request.POST.get('comment')
review = Review(
item=item,
user=request.user,
rate=rate,
comment=comment
)
review.save()
return redirect('item-detail', item_id=item_id)
context = {
'item': item,
'form': review_form
}
return render(request, "forms/review_form.html", context)
I added this in item detail view and when clicked, redirect to create review form page.
<a href="{% url 'create-review' item.id %}">Create Review</a>
Order Form
I don’t need all of the fields, so
class OrderForm(forms.ModelForm):
class Meta:
model = Order
fields = [
'firstName',
'lastName',
'email',
'address',
'city',
'province',
'postalCode',
]
and create the view. Before, cart_items should be sent to this view, so I added session in cart-list view function to send items. price should be casted to str since session is json format.
def cart_list(request):
cart, created = Cart.objects.get_or_create(user=request.user)
cart_items = CartItem.objects.filter(cart=cart)
total_amount = sum(item.quantity * item.price for item in cart_items)
cart_items_data = [
{
'item_id': item.item.id,
'item_name': item.item.name,
'quantity': item.quantity,
'price': str(item.price)
}
for item in cart_items
]
request.session['cart_items'] = cart_items_data
context = {
"cart": cart,
"cart_items": cart_items,
"total": total_amount
}
return render(request, "ecommerce/cart.html", context)
and order form view.
def order_form(request):
order_form = OrderForm()
cart_items = request.session.get('cart_items')
total_amount = sum(
float(item['quantity']) * float(item['price'])
for item in cart_items
)
if cart_items is None:
return redirect('cart-list')
if request.method == 'POST':
firstName = request.POST.get('firstName')
lastName = request.POST.get('lastName')
email = request.POST.get('email')
address = request.POST.get('address')
city = request.POST.get('city')
country = request.POST.get('country')
province = request.POST.get('province')
postalCode = request.POST.get('postalCode')
order = Order(
user=request.user,
firstName=firstName,
lastName=lastName,
email=email,
address=address,
city=city,
country=country,
province=province,
postalCode=postalCode,
)
order.save()
return redirect('item-list')
context = {
'form': order_form,
'cart_items': cart_items,
'total' :total_amount
}
return render(request, "forms/order_form.html", context)
Learned New
‘login_required’ decorator in Django is used to ensure that a user is authenticated (logged in) before they can access a particular view. If the user is not logged in, they will be automatically redirected to the login page.
from django.contrib.auth.decorators import login_required
@login_required
def user_profile(request, user_id):
...
And add this in settings.py.
# settings.py
LOGIN_URL = '/login/'