When I try to edit a stock, it returns this:
Bad Request: /api/inventory/stock/1/
[19/Jan/2025 00:14:44] “PUT {same link as above} HTTP/1.1” 400 42
This is as if the payload is not in the expected format required by django.
Django with Rest Framework
models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(blank=True, null=True)
def __str__(self):
return self.name
class RawMaterial(models.Model):
category = models.ForeignKey(Category, related_name='raw_materials', on_delete=models.CASCADE)
name = models.CharField(max_length=100)
width = models.FloatField() # Width in meters
length = models.FloatField() # Length in meters
remaining_quantity = models.FloatField() # Remaining length in meters
def __str__(self):
return f"{self.name} ({self.remaining_quantity}m left)"
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
code = models.CharField(unique=True, blank=True, max_length=20)
size = models.IntegerField(default=0)
description = models.TextField(blank=True, null=True)
price = models.FloatField(default=0)
quantity_in_stock = models.PositiveIntegerField(default=0) # Total quantity in all warehouses
def __str__(self):
return f"{self.description} (Code: {self.code} Size: {self.size}cm {self.quantity_in_stock} pcs in stock)"
def update_quantity_in_stock(self):
total_quantity = Stock.objects.filter(product=self).aggregate(models.Sum('quantity'))['quantity__sum']
self.quantity_in_stock = total_quantity if total_quantity is not None else 0
self.save()
class Warehouse(models.Model):
name = models.CharField(max_length=100)
location = models.CharField(max_length=200)
description = models.TextField(blank=True, null=True)
def __str__(self):
return self.name
class Stock(models.Model):
product = models.ForeignKey(Product, related_name='stock_entries', on_delete=models.CASCADE)
warehouse = models.ForeignKey(Warehouse, related_name='stock', on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
def __str__(self):
return f"{self.product.description} - {self.quantity} units in {self.warehouse.name}"
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.product.update_quantity_in_stock()
Welcome @hemanthkramakrishnan !
Couple different things I’d like to point out here.
First, the Django REST Framework is a third-party package, with its own support channels. While there are some people here who do attempt to address DRF-related issues, you might get faster or quicker answers from one of those resources.
Next, When posting code here, enclose the code between lines of three
backtick - ` characters. This means you’ll have a line of ```, then your code,
then another line of ```. This forces the forum software to keep your code
properly formatted. (I have taken the liberty of correcting your original posts.
Please remember to do this in the future.)
Next, when you get an error, please make sure you post the complete error along with any traceback you might get. Do not try to summarize or anonymize that information. We generally need to see the complete and accurate information to make a diagnosis.
Finally, you are more likely to attract attention to this issue if you provide a bit of a road map for the code. People are less likely to read through an entire project if they don’t have any real idea of where to look.
So I suggest you identify the specific files, functions, and models involved. In this case, this would mean including information of what views, urls and other files handling this request.
I’m building an inventory management app and this is one part of it.
1. Inventory Management App (inventory
)
This app is responsible for managing raw materials and products inventory. It also includes categories to better organize products.
- Models:
RawMaterial
: Manages inventory for raw cloth rolls (e.g., width, length, remaining quantity).
Product
: Manages inventory for finished products like shirts and pants.
Category
: Represents different categories of products (e.g., shirts, pants) with fields name
and description
.
Stock
: Records stock related to each product and Warehouse
.
- Views:
- CRUD operations for raw materials, products, and categories.
- View available stock.
- Endpoints:
/api/inventory/raw_materials/
/api/inventory/products/
/api/inventory/categories/
/api/inventory/stock/
I have Django as backend with a react frontend. I don’t have much coding background but I can understand the basics. I used chatgpt to help with my coding.
I have the Product model which includes its name, code, quantity, size, price, etc.
I have the Stock model which will update the quantity of the product from each of its entry.
I was able to show the Stock List on the page. When I added the CRUD operations to it, it seems to fail due a datatype mismatch when sending a PUT request to the API.
I have attached images for the GET request: GET.png
Even from the REST framework page “http://127.0.0.1:8000/api/inventory/stock/1/” it fails.
Here is the image for the PUT: PUT.png
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './StockList.css';
const StockList = () => {
const [stocks, setStocks] = useState([]);
const [formData, setFormData] = useState({product_id: '', quantity: '', warehouse: '' });
const [products, setProducts] = useState([]);
const [warehouses, setWarehouses] = useState([]);
const [isEditing, setIsEditing] = useState(false);
const [editingStockId, setEditingStockId] = useState(null);
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
const accessToken = localStorage.getItem('access_token');
if (accessToken) {
axios.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;
setIsAuthenticated(true);
fetchStocks();
fetchProducts();
fetchWarehouses();
} else {
setIsAuthenticated(false);
}
}, []);
const fetchStocks = () => {
axios.get('http://127.0.0.1:8000/api/inventory/stock/')
.then(response => setStocks(response.data))
.catch(error => console.error('Error fetching stocks:', error));
};
const fetchProducts = () => {
axios.get('http://127.0.0.1:8000/api/inventory/products/')
.then(response => setProducts(response.data))
.catch(error => console.error('Error fetching products:', error));
};
const fetchWarehouses = () => {
axios.get('http://127.0.0.1:8000/api/inventory/warehouses/')
.then(response => setWarehouses(response.data))
.catch(error => console.error('Error fetching warehouses:', error));
};
const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const handleSubmit = (e) => {
e.preventDefault();
const url = isEditing
? `http://127.0.0.1:8000/api/inventory/stock/${editingStockId}/`
: 'http://127.0.0.1:8000/api/inventory/stock/';
const method = isEditing ? 'put' : 'post';
const stockData = {
product_id: parseInt(formData.product_id),
quantity: Number(formData.quantity), // Ensure quantity is sent as an integer
warehouse: parseInt(formData.warehouse), // Ensure warehouse is sent as an integer
};
console.log("Submitting stock data:", formData);
axios({
method,
url,
data: stockData,
headers: {
'Content-Type': 'application/json'
}
})
.then(() => {
fetchStocks();
resetForm();
})
.catch(error => console.error(`Error ${isEditing ? 'updating' : 'creating'} stock:`, error));
};
const handleEdit = (stock) => {
setFormData({
product_id: stock.product.id,
quantity: stock.quantity,
warehouse: stock.warehouse,
});
setIsEditing(true);
setEditingStockId(stock.id);
};
const handleDelete = (id) => {
axios.delete(`http://127.0.0.1:8000/api/inventory/stock/${id}/`)
.then(() => {
fetchStocks();
})
.catch(error => {
console.error('Error deleting stock:', error);
});
};
const resetForm = () => {
setFormData({ product_id: '', quantity: '', warehouse: '' });
setIsEditing(false);
setEditingStockId(null);
};
if (!isAuthenticated) {
return <p>Please log in to view and manage stocks.</p>;
}
return (
<div className="container">
<h2>Stock List</h2>
<form onSubmit={handleSubmit} className="stock-form">
<select name="product_id" value={formData.product_id} onChange={handleChange} required>
<option value="">Select Product</option>
{products.map(product => (
<option key={product.id} value={product.id}>
{product.code}
</option>
))}
</select>
<input type="number" name="quantity" placeholder="Quantity" value={formData.quantity} onChange={handleChange} required />
<select name="warehouse" value={formData.warehouse} onChange={handleChange} required>
<option value="">Select Warehouse</option>
{warehouses.map(warehouse => (
<option key={warehouse.id} value={warehouse.id}>{warehouse.name}</option>
))}
</select>
<button type="submit">{isEditing ? 'Update' : 'Add'} Stock</button>
{isEditing && <button type="button" onClick={resetForm}>Cancel</button>}
</form>
<table className="stock-table">
<thead>
<tr><th>Product</th><th>Quantity</th><th>Warehouse</th><th>Actions</th></tr>
</thead>
<tbody>
{stocks.map(stock => (
<tr key={stock.id}>
<td>{stock.product.code}</td>
<td>{stock.quantity}</td>
<td>{stock.warehouse}</td>
<td>
<button onClick={() => handleEdit(stock)}>Edit</button>
<button onClick={() => handleDelete(stock.id)}>Delete</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default StockList;