32
loading...
This website collects cookies to deliver better user experience
bag/models.py
file:from django.contrib.auth.models import User
from django.db import models
# Create your models here.
STATUS_CHOICES = (
('BOUGHT', 'Bought'),
('PENDING', 'Pending'),
('NOT AVAILABLE', 'Not Available'),
)
class Item(models.Model):
name = models.CharField(max_length=127)
quantity = models.CharField(max_length=63)
status = models.CharField(
max_length=15, choices=STATUS_CHOICES, default='PENDING')
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField()
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
Item
class that extends the models.Model
class. Inside the class, we have mentioned the fields as discussed above. name
will be a CharField with a maximum length of up to 127 characters. Similarly, we have set quantity
to CharField too, and not IntegerField, just for the fact that quantity can be 3 Kgs as well as 3 pcs. Next, we have a status
field that is also a CharField. The status
can be one of the three- BOUGHT , PENDING and NOT AVAILABLE. To limit the choices, we have set the choices
attribute to a STATUS_CHOICES dictionary and the default value would be PENDING. We have a user
field in the model which is a ForeignKey to the User model provided by Django. This field tells that which user has created this item and will help us later in sorting them out. The next field is date
which is a DateField. The next two fields are updated_at
and created_at
which are used to maintain timestamps when the object is created and when it's updated.$ python manage.py makemigrations
$ python manage.py migrate
bag/views.py
file:from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import Item
@login_required
def add_item(request):
if request.method == "POST":
name = request.POST.get("name")
quantity = request.POST.get("quantity")
status = request.POST.get("status")
date = request.POST.get("date")
if name and quantity and status and date:
new_item = Item(name=name, quantity=quantity,
status=status, date=date, user=request.user)
new_item.save()
messages.success(request, 'Item added successfully!')
return redirect('index')
messages.error(request, "One or more field(s) is missing!")
return redirect('add-item')
return render(request, "add.html")
add.html
file. If a POST request is made, we get the values of the four fields - name , quantity , status and date. If any of the fields is empty, we flash an error and redirect to the same page. If every field is present, we create a new object of the Item model class and save it, and then redirect to the index page.from django.urls import path
from bag.views import add_item, index
urlpatterns = [
path('', index, name='index'),
path('add-item', add_item, name='add-item'),
]
add.html
file:{% extends "base.html" %}{% load static %}
{% block title %}Add to bag{% endblock title %}
{% block content %}
<body>
<div class="container mt-5">
<h1>Add to Grocery Bag</h1>
{% include 'partials/alerts.html' %}
<form method="post" action="{% url 'add-item' %}">
{% csrf_token %}
<div class="form-group mt-2">
<label>Item name</label>
<input type="text" name="name" class="form-control" placeholder="Item name" />
</div>
<div class="form-group mt-2">
<label>Item quantity</label>
<input type="text" name="quantity" class="form-control" placeholder="Item quantity" />
</div>
<div class="form-group mt-2">
<label>Item status</label>
<select class="form-control" name="status">
<option value="PENDING">PENDING</option>
<option value="BOUGHT">BOUGHT</option>
<option value="NOT AVAILABLE">NOT AVAILABLE</option>
</select>
</div>
<div class="form-group mt-2">
<label>Date</label>
<input type="date" name="date" class="form-control" placeholder="Date" />
</div>
<div class="form-group mt-2">
<input type="submit" value="Add" class="btn btn-danger" />
</div>
</form>
</div>
</body>
{% endblock content %}
bag/views.py
file:@login_required
def update_item(request, item_id):
item = Item.objects.get(id=item_id)
date = item.date.strftime("%d-%m-%Y")
if request.method == 'POST':
item.name = request.POST.get("name")
item.quantity = request.POST.get("quantity")
item.status = request.POST.get("status")
item.date = request.POST.get("date")
item.save()
messages.success(request, 'Item updated successfully!')
return redirect('index')
return render(request, "update.html", {'item': item, 'date': date})
add_item
function. But there is a change. With the request, we are getting the item_id
in the request URL. Using that item_id
, we first fetch the item from the database so that the user can view the previous values in the update form. Whenever a GET request is made, the item and date is passed with the request. If a POST request is made, we get the values from the form and update the appropriate fields and save the item.from django.urls import path
from bag.views import add_item, index, update_item
urlpatterns = [
path('', index, name='index'),
path('add-item', add_item, name='add-item'),
path('update-item/<int:item_id>', update_item, name='update-item'),
]
<int:item_id>
so that we get the item_id
in our view function.update.html
file:{% extends "base.html" %}{% load static %}
{% block title %}Update bag{% endblock title %}
{% block content %}
<body>
<div class="container mt-5">
<h1>Update Grocery Bag</h1>
<form method="post" action="{% url 'update-item' item.id %}">
{% csrf_token %}
<div class="form-group mt-2">
<label>Item name</label>
<input
type="text"
class="form-control"
placeholder="Item name"
name="name"
value="{{item.name}}"
/>
</div>
<div class="form-group mt-2">
<label>Item quantity</label>
<input
type="text"
class="form-control"
placeholder="Item quantity"
name="quantity"
value="{{item.quantity}}"
/>
</div>
<div class="form-group mt-2">
<label>Item status</label>
<select class="form-control" name="status" id="status">
<option value="PENDING">PENDING</option>
<option value="BOUGHT" selected>BOUGHT</option>
<option value="NOT AVAILABLE">NOT AVAILABLE</option>
</select>
</div>
<div class="form-group mt-2">
<label>Date</label>
<input
type="date"
class="form-control"
placeholder="Date"
name="date"
id="date"
/>
</div>
<div class="form-group mt-2">
<input type="submit" value="Update" class="btn btn-danger" />
</div>
</form>
</div>
<script>
// Select appropriate option
var options = document.getElementById('status').options;
for (let index = 0; index < options.length; index++) {
if(options[index].value == '{{item.status}}'){
options[index].selected = true;
}
}
// Select date
var fullDate = '{{date}}';
var dateField = document.getElementById('date');
dateField.value = `${fullDate.substring(6,12)}-${fullDate.substring(3,5)}-${fullDate.substring(0,2)}`
</script>
</body>
{% endblock content %}
item.id
passed with it. Notice that we have added name attribute in each form field, as this is required to fetch the value in our backend. The next thing to be considered is the Javascript code at the below of the above script. The Javascript code is used to select the status and date automatically. @login_required
def delete_item(request, item_id):
item = Item.objects.get(id=item_id)
item.delete()
messages.error(request, 'Item deleted successfully!')
return redirect('index')
item_id
in the delete_item
view function. We fetch that item and delete it and then redirect the user to the index page with a flash.from django.urls import path
from bag.views import add_item, delete_item, index, update_item
urlpatterns = [
path('', index, name='index'),
path('add-item', add_item, name='add-item'),
path('update-item/<int:item_id>', update_item, name='update-item'),
path('delete-item/<int:item_id>', delete_item, name='delete-item'),
]
index.html
file. But now we need to fetch all the items added by the user and send it to the frontend. So, let's update the index view function:@login_required
def index(request):
items = Item.objects.filter(user=request.user).order_by('-id')
context = {
'items': items
}
return render(request, "index.html", context)
{% extends "base.html" %}{% load static %}
{% block title %}View Bag{% endblock title %}
{% block content %}
<body>
<div class="container mt-5">
<!-- top -->
<div class="row">
<div class="col-lg-6">
<h1>View Grocery List</h1>
<a href="{% url 'add-item' %}">
<button type="button" class="btn btn-success">Add Item</button>
</a>
</div>
<div class="col-lg-6 float-right">
<div class="row">
<div class="col-lg-6">
<!-- Date Filtering-->
<input type="date" class="form-control" />
</div>
<div class="col-lg-4">
<input type="submit" class="btn btn-danger" value="filter" />
</div>
<div class="col-lg-2">
<p class="mt-1"><a href="{% url 'signout' %}">Log Out</a></p>
</div>
</div>
</div>
</div>
<br>
{% include 'partials/alerts.html' %}
<!-- Grocery Cards -->
<div class="row mt-4">
<!-- Loop This -->
{% for item in items %}
<div class="col-lg-4 mb-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{item.name}}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{item.quantity}}</h6>
{% if item.status == 'PENDING' %}
<p class="text-info">{{item.status}}</p>
{% elif item.status == 'BOUGHT' %}
<p class="text-success">{{item.status}}</p>
{% else %}
<p class="text-danger">{{item.status}}</p>
{% endif %}
<div class="row">
<div class="col-md-6">
<a href="{% url 'update-item' item.id %}">
<button type="button" class="btn btn-primary">UPDATE</button>
</a>
</div>
<div class="col-md-6">
<a href="{% url 'delete-item' item.id %}">
<button type="button" class="btn btn-danger">DELETE</button>
</a>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</body>
{% endblock content %}
items
using an iterator item
. Also we have used if condition to add colors to the status. We have two buttons - update and delete with the URLs set to the update and delete route respectively. $ python manage.py createsuperuser
http://127.0.0.1:8000/admin
route, and login with your credentials.