HOW TO KEEP THE PREVIOUS VERSION OF DATA OR THE MODEL WITHOUT USING TRIGGER (For Any Database Type)
We have a look into this topic previously (Keeping the previous version of a Django model) but we used a trigger to implement the logic.
This was fine for only MySQL user only. If you are using PosgreSQL or another type of Database engine, you might have found that it wasn’t working.
In this video, I will show you how to archive this with any type of Database server, including SQLite3 database.
Django has inbuilt data manipulation functions that can be used to save data in the database. See examples in the codes below.
In this section of the tutorial, we are going to keep the previous version of our data and use it as our stock update history.
We can archive this by copying the content of the updated data into another table called StockHistory
.
1. Create another table similar to the Stock table. We will use Django models to create it as follows:
class StockHistory(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True, null=True)
item_name = models.CharField(max_length=50, blank=True, null=True)
quantity = models.IntegerField(default='0', blank=True, null=True)
receive_quantity = models.IntegerField(default='0', blank=True, null=True)
receive_by = models.CharField(max_length=50, blank=True, null=True)
issue_quantity = models.IntegerField(default='0', blank=True, null=True)
issue_by = models.CharField(max_length=50, blank=True, null=True)
issue_to = models.CharField(max_length=50, blank=True, null=True)
phone_number = models.CharField(max_length=50, blank=True, null=True)
created_by = models.CharField(max_length=50, blank=True, null=True)
reorder_level = models.IntegerField(default='0', blank=True, null=True)
last_updated = models.DateTimeField(auto_now_add=False, auto_now=False, null=True)
timestamp = models.DateTimeField(auto_now_add=False, auto_now=False, null=True)
Note that we are setting all the fields to accept blank data blank=True, null=True
and the date fields to auto_now_add=False
, auto_now=False
This will give us the flexibility to pass data into it or leave it blank.
2. Do makemigration
and migrate
for the table called StockAudit
to be created../manage.py makemigration
./manage.py migrate
3. Open MySQL workbench or any other database client, update the properties of the StockHistory table and remove all checkboxes on all fields.
4. Update the issue_item and receive_item view to include the functions that will copy the content of the new data into the history table. Then call the save function.
For Issue Items
issue_history = StockHistory(
id = instance.id,
last_updated = instance.last_updated,
category_id = instance.category_id,
item_name = instance.item_name,
quantity = instance.quantity,
issue_to = instance.issue_to,
issue_by = instance.issue_by,
issue_quantity = instance.issue_quantity,
)
issue_history.save()
For Receive Items
receive_history = StockHistory(
id = instance.id,
last_updated = instance.last_updated,
category_id = instance.category_id,
item_name = instance.item_name,
quantity = instance.quantity,
receive_quantity = instance.receive_quantity,
receive_by = instance.receive_by
)
receive_history.save()
5: Make a view to list the content of the StockHistory
table. Note that the queryset
is defined to pull data from the StockHistory
model and not Stock model. Don’t forget to import the StockHistory
model.
@login_required
def list_history(request):
header = 'LIST OF ITEMS'
queryset = StockHistory.objects.all()
context = {
"header": header,
"queryset": queryset,
}
return render(request, "list_history.html",context)
6. Create a template for history data and name it list_history.html
<div class="display_table">
<table class='table'>
<thead>
<tr>
<th>COUNT</th>
<th>ID</th>
<th>CATEGORY</th>
<th>ITEM NAME</th>
<th>QUANTITY IN STORE</th>
<th>ISSUE QUANTITY</th>
<th>RECEIVE QUANTITY</th>
<th>LAST UPDATED</th>
</tr>
</thead>
{% for instance in queryset %}
<tr>
<td>{{forloop.counter}}</td>
<td>{{instance.id}}</td>
<td>{{instance.category}}</td>
<td><{{instance.item_name}}</td>
<td>{{instance.quantity}}</td>
<td>{{instance.issue_quantity}}</td>
<td>{{instance.receive_quantity}}</td>
<td>{{instance.last_updated}}</td>
</tr>
{% endfor %}
</table>
</div>
7: Make a URL for stockhistory list, and add the link in navbar.html
Add a URL in urls.py:
path('list_history/', views.list_history, name='list_history'),
8. Now add stock history link in navbar.html
<li class="nav-item">
<a class="nav-link" href="/list_history">List History</a>
</li>
HI…. arbadjie, I have been waiting for this tutorial but it does not record all issues and received transactions. it’s replacing the quantity only, when we issue, it makes received quantity “0” and when we received it make issue quantity “0”. Please can you make one tutorial which keeps all transactions recorded in the next to each row:
Please watch the whole video. I already explained that you will need to remove some lines of code if not you will have a issue and receive with “0” as you are experiencing.
just keeps over writing…wonder if anyone has succeeded..
like if issue the same item twice only one (latest) record wil b kept
Anyone having the same issue?
yes me
I have figured out the problem.
I am not using foreignkey and category_id
so whenever i am saving it is writing the same id ( id = instance.id,
just remove this it will work
It’s great that you work it out. You are a start
Please can you explain in detail what you did exactly
It is not clear.
I guess you repeat the video. That might help
Hello, at first i need to thank you for the amazing tutorials you are providing and wish i can donate for you but we have economical crisis in our country and can t use cards to transfer money.
i need your help. i need to save the history for every issue and transfer without using at all workbench is it possible?
and if possible to add in history all actions like save and delete and every action done.
I would appreciate your help
Thanks for your intention. I covered that in this video. It should work for the SQLite DB
Hello! Your tutorials are very cool stuff. But doing everything by appointment is only the first step. I decided to modify this application a little – I would like to add a page with delivery and calendar. For example, a customer chooses a product and a delivery date. On our page with the calendar, you can see entries for the month, when where the delivery is – like a google calendar. Can you suggest me where can I look and how best to implement it?
Great suggestion. I’ve not done this yet but I will like to research it and make a video on it. In the meantime, if you have a solution, please post the resources here. I will be very grateful for that.
the entry of the same product is overwritten by the new instance. But the code saves different products correctly but not every instance of the same products.
This has been brought to my attention. I will work on a solution and make a follow-up video. Thank you for the feedback
Hello Mr Arbadjie please you did post the tutorial on how to create a button to check for the items that have reached the reorder level. Can the procedure be given here? Thank you Sir
hey my list history page isnt being updated by the trigger and theres no rows in the workbench
The trigger has to update the table first before history list the data. Check trigger statement
You have done wonderful work. I really appreciate it. I have finished your project according to my requirements. I need to shift my project to another computer with windows. but I am facing too many issues I tried to search them on the internet but every time a new issue raises. Would you please guide my how to shift my project from one machine to another.
Let me see if I can do a video on that.