Decrement model value in django - django-models

It's my first time using django to clear my schoolwork, I want to lower Stock in my Book class by Quantity value,
ex.
Stock = 10 and Quantity = 1
Stock = 9 because 10 - 1 for Stock - Quantity
this is my code
main.html
{% load static %}
<html>
<head>
<title>
Bookstore Management System
</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
{% include 'book/navbar.html' %}
{% block content %}
{% endblock %}
<br>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
</html>
home.html
{% extends 'book/main.html' %}
{% block content %}
<br>
<div class="container jumbotron">
<div class="container row">
<div class="col-lg-10">
<table class="table table-sm">
<tr>
<th>title</th>
<th>Author</th>
<th>Edition</th>
<th>Stock</th>
<th>Price</th>
</tr>
{% for book in books %}
<tr>
<td>{{book.title}}</td>
<td>{{book.Author}}</td>
<td>{{book.Edition}}</td>
<td>{{book.Stock}}</td>
<td>{{book.Price}}</td>
<td><a class="btn btn-sm btn-info" href="{% url 'addtocart' book.id %}">Add to cart</a></td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
{% endblock %}
viewcart.html
{% extends 'book/main.html' %}
{% load static %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-lg-10"></div>
<br>
<h5>BOOKS:</h5>
<div class="card card-body">
<table>
<tr>
<th>title</th>
<th>Author</th>
<th>Edition</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
{% for book in cart.books.all %}
<tr>
<td>{{book.title}}</td>
<td>{{book.Author}}</td>
<td>{{book.Edition}}</td>
<td>{{book.Quantity}}</td>
<td>{{book.Price}}</td>
<td>{{book.Total}}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
{% endblock %}
Model.py
from django.db import models
from django.db.models import F
from django.contrib.auth.models import User
class Book(models.Model):
title=models.CharField(max_length=300, null=True)
Author=models.CharField(max_length=300, null=True)
Edition=models.IntegerField()
Price=models.IntegerField()
Stock=models.IntegerField()
Quantity=models.IntegerField()
Total=models.IntegerField()
def decrementStock(self):
self.Quantity += 1
self.update(Stock=F('Stock') - F('Quantity'))
self.save()
def Tprice(self):
self.update(Total=F('Price') * F('Quantity'))
self.save()
def _str_(self):
return str(self.title)
class Customer(models.Model):
user=models.OneToOneField(User, null=True, on_delete=models.CASCADE)
name=models.CharField(max_length=200, null=True)
phone=models.CharField(max_length=200, null=True)
email=models.CharField(max_length=200, null=True)
date_created=models.DateTimeField(auto_now_add=True, null=True)
def _str_ (self):
return str(self.name)
class Cart(models.Model):
customer=models.OneToOneField(Customer, null=True, on_delete=models.CASCADE)
books=models.ManyToManyField(Book)
def _str_ (self):
return str(self.customer)
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import *
from django.contrib.auth import login,logout,authenticate
from .forms import *
def home(request):
books=Book.objects.all()
context={'books':books}
if request.user.is_staff:
return render(request, 'book/adminhome.html', context)
else:
return render(request, 'book/home.html', context)
def logoutPage(request):
logout(request)
return redirect('/')
def loginPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
if request.method=="POST":
username=request.POST.get('username')
password=request.POST.get('password')
user=authenticate(request,username=username, password=password)
if user is not None:
print("working")
login(request,user)
return redirect('/')
context ={}
return render(request,'book/login.html',context)
def registerPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
form=createuserform()
cust_form=createcustomerform()
if request.method=='POST':
form=createuserform(request.POST)
cust_form=createcustomerform(request.POST)
if form.is_valid() and cust_form.is_valid:
user=form.save()
customer=cust_form.save(commit=False)
customer.user=user
customer.save()
return redirect('login')
context={
'form':form,
'cust_form':cust_form
}
return render(request,'book/register.html', context)
def addbook(request):
form=createbookform()
if request.method=='POST':
form=createbookform(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context={'form':form}
return render(request,'book.addbook.html', context)
def viewcart(request):
cust=Customer.objects.filter(user=request.user)
for c in cust:
carts=Cart.objects.all()
for cart in carts:
if(cart.customer==c):
context={
'cart':cart
}
return render(request, 'book/viewcart.html', context)
else:
return render(request,'book/emptycart.html')
def addtocart(request,pk):
book=Book.objects.get(id=pk)
Book.objects.get(Quantity=pk).decrementStock()
cust=Customer.objects.filter(user=request.user)
for c in cust:
carts=Cart.objects.all()
reqcart=''
for cart in carts:
if(cart.customer==c):
reqcart=cart
break
if(reqcart==''):
reqcart=Cart.objects.create(
customer=c,
)
reqcart.books.add(book)
return redirect('/')
in model.py and views.py are wrong but i dont know to fix it
sorry for my bad english writing and i thank you for poeple to helped me.
I try by editing model.py by using this but its failed and get these error
`
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/addtocart/1
Django Version: 3.2
Python Version: 3.10.7
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'book']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "C:\coding python\MHB\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\coding python\MHB\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\coding python\MHB\Scripts\bookstore\book\views.py", line 80, in addtocart
Book.objects.get(Quantity=pk).decrementStock()
File "C:\coding python\MHB\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\coding python\MHB\lib\site-packages\django\db\models\query.py", line 435, in get
raise self.model.DoesNotExist(
Exception Type: DoesNotExist at /addtocart/1
Exception Value: Book matching query does not exist.
`

Related

Django Model Method access from template

I cannot render in a template the method get_total_hoy, what it does is get the total sales of products of the currrent day;
class VentaProductos(models.Model):
producto = models.ForeignKey(
Productos, null= True, on_delete=models.SET_NULL)
medio_de_venta = models.ForeignKey(MediosVenta, null=True, blank=False, on_delete=models.SET_NULL)
precio_de_venta = models.FloatField(null=True, blank=True)
fecha_venta = models.DateField(blank=False, null=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
vendido_por = models.CharField(max_length=20, null=False, blank=False)
class Meta:
verbose_name_plural = "Venta de Productos"
ordering = ["-id"]
def __str__(self):
return f"{self.producto.nombre}"
def get_total_hoy(self):
today = timezone.now()
total = VentaProductos.objects.filter(fecha_venta=today).aggregate(total = Sum('precio_de_venta'))
total_productos = total['total']
print(total_productos)
return total_productos
in my template I have the following table:
<h2>Ventas de hoy</h2>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Nombre</th>
<th scope="col">Precio</th>
<th scope="col">Fecha</th>
<th scope="col">vendido por</th>
</tr>
</thead>
<tbody>
{% for producto in ventaproductos_list %}
<tr>
<th scope="row">{{forloop.counter}}</th>
<td>{{producto.producto}}</td>
<td>${{producto.precio_de_venta}}</td>
<td>{{producto.fecha_venta}}</td>
<td>{{producto.vendido_por}}</td>
</tr>
{% endfor %}
<tr>
<td>${{ventaproductos.get_total_hoy}}</td>
</tr>
</tbody>
</table>
I'm trying to display that total at the end of the table.
My understanding is that if my method does not required extra parameters there is no need to access it as context in the view and I can access directly. Anyway I this is my current view (if it helps):
class Home(ListView):
model = VentaProductos
template_name= 'main/home.html'
def get_queryset(self):
today = timezone.now()
return VentaProductos.objects.filter(fecha_venta = today)

Implementing #check_honeypot on Django Wagtail Form

I am trying to implement Honeypot into a Wagtail email form, but I don't understand how to add the #check_honeypot decorator to a class in models.py, which checks the honeypotfor validity.
To set up Honeypot, it requires that I add the #check_honeypot decorator to the form view in my views.py. Unfortunately, wagtail does not utilize views.py and instead the form is built in the models.py.
How to I implement honeypot decorator onto a Wagtail form?
Honeypot repo: https://github.com/jamesturk/django-honeypot
Snippet from honeypot instructions:
To ensure that the honeypot field is both present and correct you will >need to use check_honeypot decorator from honeypot.decorators:
from honeypot.decorators import check_honeypot
#check_honeypot(field_name='hp_field_name')
def post_comment(request):
...
#check_honeypot
def other_post_view(request):
...
SOLUTION:
#method_decorator(check_honeypot)
def render_landing_page
models.py
class FormField(AbstractFormField):
page = ParentalKey('FormPage', on_delete=models.CASCADE, related_name='form_fields')
class FormPage(AbstractEmailForm):
header = RichTextField(blank=True)
body = RichTextField(blank=True)
header_two = RichTextField(blank=True)
body_two = RichTextField(blank=True)
header_three = RichTextField(blank=True)
body_three = RichTextField(blank=True)
address = RichTextField(blank=True)
form_header = models.CharField(blank=True, max_length=100)
thank_you_text = RichTextField(blank=True)
content_panels = AbstractEmailForm.content_panels + [
FieldPanel('header', classname="full"),
FieldPanel('body', classname='full'),
FieldPanel('header_two', classname="full"),
FieldPanel('body_two', classname='full'),
FieldPanel('header_three', classname="full"),
FieldPanel('body_three', classname='full'),
FieldPanel('address', classname='full'),
FieldPanel('form_header', classname='full'),
InlinePanel('form_fields', label="Form fields"),
FieldPanel('thank_you_text', classname="full"),
MultiFieldPanel([
FieldRowPanel([
FieldPanel('from_address', classname="col6"),
FieldPanel('to_address', classname="col6"),
]),
FieldPanel('subject'),
], "Email"),
]
thank_you_page = models.ForeignKey(
'wagtailcore.Page',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)
def render_landing_page(self, request, form_submission=None, *args, **kwargs):
if self.thank_you_page:
url = self.thank_you_page.url
# if a form_submission instance is available, append the id to URL
# when previewing landing page, there will not be a form_submission instance
if form_submission:
url += '?id=%s' % form_submission.id
return redirect(url, permanent=False)
# if no thank_you_page is set, render default landing page
return super().render_landing_page(request, form_submission, *args, **kwargs)
content_panels = AbstractEmailForm.content_panels + [
FieldPanel('header', classname="full"),
FieldPanel('body', classname='full'),
FieldPanel('header_two', classname="full"),
FieldPanel('body_two', classname='full'),
FieldPanel('header_three', classname="full"),
FieldPanel('body_three', classname='full'),
FieldPanel('address', classname='full'),
FieldPanel('form_header', classname='full'),
InlinePanel('form_fields'),
FieldPanel('thank_you_text', classname='full'),
PageChooserPanel('thank_you_page'),
MultiFieldPanel([
FieldRowPanel([
FieldPanel('from_address', classname='col6'),
FieldPanel('to_address', classname='col6'),
]),
FieldPanel('subject'),
], 'Email'),
]
form.html
<section class="contact-background-lg" >
<div class="container px-0">
<div class="card p-m-5-0">
<form action="{% pageurl page %}" method="POST">
{% csrf_token %}
{% render_honeypot_field "phonenumber" %}
<div class="row">
<div class="col-md-12 col-sm-12">
{% if form.non_field_errors %}
<div class="alert alert-danger" role="alert">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
<div class="card-title text-primary">
<h2><strong>{{ page.form_header }}</strong></h2><p class="pb-2 text-muted">Please complete the form below to receive a response within 24 hours.</p>
<hr>
<br>
</div>
</div>
{% for field in form.visible_fields %}
<div class="col-md-6 col-sm-12">
<div class="form-group pt-3">
{{ field.label_tag }}
{% render_field field class+="form-control" %}
</div>
</div>
{% endfor %}
</div>
<div class="pull-center">
<button type="submit" class="btn btn-primary-alt py-3 mt-3" style="width: 8rem;">Submit</button>
</div>
</form>
</div>
</div>
</section>

Model data not showing on template when iterating over queryset

So when building a simple Django website I found that for some reason I can't iterate over a queryset of a model I made and display the data in the template that I'm trying to create.
I have changed the keys of the dictionary being passed into the views and I have saved data on the model's database and changed around the template's format.
The database has values I checked using the Python Shell.
This is the template code:
<div class="container-fluid mt-3" >
<h2 class="display-4"><center>Upcoming Events:</center></h2>
{ % for post in Posts % }
<div class="row mt-3 ">
<div class="col-sm-1">
</div>
<div class="col-md">
<h4> { { post.title } } </h4>
<p class="lead">
{ { post.text } }
</p>
</div>
<div class="col-md">
<img class="img-fluid mx-auto" src="static_files/pictures/logo_main.png">
</div>
<div class="col-sm-1">
</div>
</div>
{ % endfor % }
This is the views code that is interacting with the template:
def home_view(request, *args, **kwargs):
Posts_ = Posts.objects.all()
context = {
'Posts':Posts_
}
return render(request, "home.html", context)
This is the model of interest:
class Posts(models.Model):
title = models.CharField(max_length=140)
text = models.TextField(blank=True, null=True)
date_posted = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
You have put extra space between the curly braces, that is wrong syntax. You need to change:
{ { post.title } } to {{ post.title }}
{ { post.text } } to {{ post.text }}

Silex + Twig + SQL Server : rendering pictures

I have some pictures in a SQL Server database in a BLOB column.
I need to get them and show up to the HTML page.
But in the result on the HTML page, I have the long string in src attribute instead of the pictures.
Silex code:
<!-- language-all: php -->
$pict->get('/show_pic/{id}', function ($id) use ($app) {
//Request of photos
$photos=getPhotoByID($id, $app);
return $app['twig']->render('test/template_show_pictures.html.twig', array('photos'=>$photos));
})->bind('show_pic');
function getPhotoByID($ID, $app)
{
$sql = "<some SQL here>";
$statement = $app['dbs']['mssql']->prepare($sql);
$statement->bindValue(1, $ID, "text");
$statement->execute();
$photo = $statement->fetchAll();
if (empty($photo)) {
return "We don't have a photo with id=".$ID;
}
return $photo;
}
Twig file:
<!-- language: twig -->
{% extends 'test/test_base.html.twig' %}
{% block title %}Pictures from DB{% endblock %}
{% block content %}
{% for im in photos %}
<img alt="Embedded Image" src="data:image/jpeg;base64,{{ im['Foto'] }}" />
{% endfor %}
{% endblock %}
HTML markup :
<!-- language: lang-html -->
<!DOCTYPE html>
<html>
<head>
<title>Pictures from DB</title>
<link rel="stylesheet" href="/css/print.css">
</head>
<body>
<div class="page">
<img alt="Embedded Image" src="data:image/jpeg;base64,���JFIF...too many symbols here" />
</div>
</body>
</html>
What is wrong with it?
You should encode image with base64
Add filter for encoding to base64:
$app->extend('twig', function ($twig, $app) {
$twig->addFilter('base64_encode', new \Twig_SimpleFilter('base64_encode', function ($value) {
return \base64_encode($value);
}));
return $twig;
});
And use it in template:
{{ im['Foto']|base64_encode }}

Angularjs filling a table

I am not able to enter a list in a table within the html of the body. This list came using Angularjs, ajax request with django. The incoming list contains other lists within it, which can vary in size every query. Example: [["a","b","c"],["a","b","c"],["a","b","c"]] or [["a","b","c","d","e"],["a","b","c","d","e"],["a","b","c","d","e"]]
File dfp_consulta.js
function ListDropdown($scope, $http) {
$scope.bvmf = {ccvms : [ '1023', '10456', '10472'],
consolidados : [ 't', 'f' ],
origens : [ 'ITR', 'DFP' ],
balancos : [ '1', '2', '3', '4'],
periodos : [ '1-3', '1-6', '1-9', '1-12' ],
anos : [ '1997', '1998', '1999', '2012' ]
$scope.range=[]
$scope.send=function(ccvm, consolidado, origem, balanco, periodo, ano, ano_doc){
$http({
method:'POST',
url:'/sending/',
data:ccvm+consolidado+origem+balanco+periodo+ano+ano_doc,
headers:{'Content-Type': 'application/x-www-form-urlencoded'},
}).success(function(c){
$scope.range=c
})
}
}
File dfp_consulta.html
{% extends "base.html" %}
{% block corpo %}
<div ng-app="" ng-controller="ListDropdown">
<select ng-model="ccvm" ng-options="ccvm as ccvm for ccvm in bvmf.ccvms"></select><br>
<select ng-model="consolidado" ng-disabled="!ccvm" ng-options="consolidado for consolidado in bvmf.consolidados" ></select><br>
<select ng-model="origem" ng-disabled="!consolidado" ng-options="origem for origem in bvmf.origens" ></select><br>
<select ng-model="balanco" ng-disabled="!origem" ng-options="balanco for balanco in bvmf.balancos" ></select><br>
<select ng-model="periodo" ng-disabled="!balanco" ng-options="periodo for periodo in bvmf.periodos" ></select><br>
<select ng-model="ano" ng-disabled="!periodo" ng-options="ano for ano in bvmf.anos" ></select><br>
<select ng-model="ano_doc" ng-disabled="!ano" ng-options="ano_doc for ano_doc in bvmf.anos" ng-change="send(ccvm,consolidado,origem,balanco,periodo,ano,ano_doc)"></select><br>
<table class='table table-hover'>
{% for i in range %}
<tr>
{% for s in i %}
<td>{{ s }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
</div>
{% endblock %}
I am getting in $scope.range for example, the following list [["a", "b", "c"] ["a", "b", "c"] ["a", "b "," c "]], however, {% for i in range %} is not using the range array
The problem is that both Django and AngularJS share the same syntax of Jinja2 for variable substitution in templates.
The easiest option would be to tell Django not to use it's syntax in places you need to use angularjs variable substitution - in other words, use verbatim tag:
{% block corpo %}
{% verbatim %}
<div ng-app="" ng-controller="ListDropdown">
<select ng-model="ccvm" ng-options="ccvm as ccvm for ccvm in bvmf.ccvms"></select><br>
<select ng-model="consolidado" ng-disabled="!ccvm" ng-options="consolidado for consolidado in bvmf.consolidados" ></select><br>
<select ng-model="origem" ng-disabled="!consolidado" ng-options="origem for origem in bvmf.origens" ></select><br>
<select ng-model="balanco" ng-disabled="!origem" ng-options="balanco for balanco in bvmf.balancos" ></select><br>
<select ng-model="periodo" ng-disabled="!balanco" ng-options="periodo for periodo in bvmf.periodos" ></select><br>
<select ng-model="ano" ng-disabled="!periodo" ng-options="ano for ano in bvmf.anos" ></select><br>
<select ng-model="ano_doc" ng-disabled="!ano" ng-options="ano_doc for ano_doc in bvmf.anos" ng-change="send(ccvm,consolidado,origem,balanco,periodo,ano,ano_doc)"></select><br>
<table>
<tr ng-model="item2" ng-repeat="item2 in range">
<td ng-repeat="item3 in item2">{{ item3 }}</td>
</tr>
</table>
</div>
{% endverbatim %}
{% endblock %}
The new table structure allows the build with angularjs amounts different of row and column <tr ng-repeat> and <td ng-repeat>
See also:
Integrate AngularJS with Django
Stackoverflow - Django not working with Angularjs

Resources