I'm trying to create an inventory management system. I'm having problems figuring out how to add multiple inventory items into my order from a table. I want to achieve this by selecting the item by the checkbox and also adding the quantity. I also eventually want to add a search bar to search through the table
html
<form method="POST" action="">
{% csrf_token %}
{% for field in form %}
<div class="form-group row">
<Label for="id_{{ field.name }}" class="col-2 col-form-label">{{ field.label }}</Label>
<div class="col-10">
{{ field }}
</div>
</div>
{% endfor %}
<table class="table table-striped">
<tbody>
{% for item in Inventory %}
<tr>
<td> <input type="checkbox" name="itemCheck" value="{{ item.pk }} "></td>
<td> <input name="itemQuantity"> </td>
<td> {{ item.name }} </td>
<td> {{ item.quantity }} </td>
<td> <span class="badge badge-pill badge-success">{{item.status}}</span></td>
<td> ${{ item.sale_price }} </td>
</td>
</tr>
{% endfor %}
</tbody>
</table>
views.py
def create_order(request):
order_form = OrderForm(request.POST)
if request.method == 'POST':
if formset.is_valid():
total = 0
order = Orders(total=total)
order.save()
order_form.save()
selected_items = request.POST.getlist('itemCheck')
print(selected_items) # This returns the primary keys of the selected items
context = {"form": order_form, "Inventory": Inventory.objects.all()}
return render(request, 'create_order.html', context)
models
class Inventory(models.Model):
name = models.CharField(max_length=128, blank=False)
...
def __str__(self):
return f"{self.id} - {self.name}"
class Orders(models.Model):
studio = models.CharField(max_length=64)
status = models.CharField(max_length=64, default="warehouse", blank=False)
total = models.DecimalField(max_digits=10, decimal_places=2)
class OrderEquipment(models.Model):
equipment = models.ForeignKey(Inventory, blank=False, on_delete=models.CASCADE)
order = models.ForeignKey(Orders, on_delete=models.CASCADE)
quantity = models.IntegerField(blank=False)
For the sake of simplicity, since you didn't post your formset and other code, I'm going to assume your HTML and formset are coming in correctly and just focus on the table/model loading. I have found the best way to load many items is to use bulk_create(). You may need to fidget around with the below code, but it should get you on the right track.
from django.db import transaction
try:
with transaction.atomic():
# I put cleaned_data below. You need to replace with your Orders data if different.
order = Orders.objects.create(**cleaned_data)
# Loop thru OrderEquipment Items. I'm guessing your 'selected_items' is the inventory data, (equipment and quantity).
orderequip_list = []
for equip in selected_items:
orderequip_list.append(OrderEquipment(order=order, **equip))
OrderEquipment.objects.bulk_create(orderequip_list)
except (IntegrityError, ObjectDoesNotExist):
order = None
Related
My form:
class TestCaseUpdateForm(forms.ModelForm):
class Meta:
model = TestCase
fields = ( 'name', 'executable', 'parameter_list', 'executable_type', 'test_type' , 'project_name', 'created_by')
My views:
class EditCaseView(UpdateView):
model = TestCase
form_class = TestCaseUpdateForm
template_name_suffix = '_update_form'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
pk = self.kwargs.get(self.pk_url_kwarg)
queryset = self.get_queryset().filter(pk=pk)
case = queryset.get()
context['my_case'] = case
context['my_exetype'] = TestCase.EXECUTABLE_TYPE_CHOICES
context['my_ttype'] = TestCase.TEST_TYPE_CHOICES
context['projnames'] = PROJNAME_CHOICES
return context
def get_success_url(self):
print("get_success_url")
return reverse("integratedTest:testCase")
My model:
PROJNAME_CHOICES = (
('Name1', 'Name1'),
('Name2','Name2'),
('Name3','Name3')
)
class TestCase(models.Model):
EXECUTABLE_TYPE_CHOICES = (
('e_type1', 'e_type1'),
('e_type2', 'e_type2'),
('e_type3', 'e_type3'),
)
TEST_TYPE_CHOICES = (
('t_type1', 't_type1'),
('t_type2','t_type2'),
('others', 'others'),
)
name = models.CharField(max_length=200, unique=True)
executable = models.CharField(max_length=1023)
parameter_list = models.TextField(blank=True, default = "")
project_name = models.CharField(max_length=200, choices = PROJNAME_CHOICES, default="Name1")
executable_type = models.CharField(max_length=200, choices = EXECUTABLE_TYPE_CHOICES, default = "e_type1")
test_type = models.CharField(max_length=200, choices = TEST_TYPE_CHOICES, default = "t_type1")
created_by = models.CharField(max_length=200, default = "sb")
create_datetime = models.DateTimeField("testcase created on", auto_now = True)
My template:
<form method="post">{% csrf_token %}
<h1 >Edit Test Case:</h1>
<table>
<tr>
<th>Name:</th>
<th>executable:</th>
<th>parameter_list:</th>
</tr>
<tr>
<td><input type="text" id="id_name" name="name" value = "{{my_case.name}}"
placeholder="short_unique_string" required>
</td>
<td>
<input type="text" id="id_executable" name="executable" value = "{{my_case.executable}}"
placeholder="FilenameWithoutPath.py" required>
</td>
<td><textarea id="id_parameter_list" name="parameter_list" value = "{{my_case.parameter_list}}"
placeholder="Copy your parameter string here directly"></textarea>
</td>
</tr>
<tr>
<th>executable_type:</th>
<th>test_type:</th>
<th>project_name:</th>
<th>created_by:</th>
</tr>
<tr>
<td>
<select name="executable_type" id="id_executable_type" required>
{%for key, value in my_exetype %}
{%if my_case.executable_type == key %}
<option value={{value}} selected>{{key}}</option>
{%else%}
<option value={{value}}>{{key}}</option>
{%endif%}
{%endfor%}
</select>
</td>
<td>
<select name="test_type" id="id_test_type" required>
{%for key, value in my_ttype %}
{%if my_case.test_type == key %}
<option value={{value}} selected>{{key}}</option>
{%else%}
<option value={{value}}>{{key}}</option>
{%endif%}
{%endfor%}
</select>
</td>
<td>
<select name="project_name" id="id_project_name" >
{%for key, value in projnames %}
{%if my_case.project_name == key %}
<option value={{value}} selected>{{key}}</option>
{%else%}
<option value={{value}}>{{key}}</option>
{%endif%}
{%endfor%}
</select>
</td>
<td><input type="text" id="id_created_by" name="created_by" value = "{{my_case.created_by}}"
placeholder="some name like 'sb'" required></td>
</tr>
</table>
{% for i in form.errors %}
{{i}}
{% endfor %}
<br>
{% if form.errors %}
error!
{% endif %}
<input type="submit" value="Update">
</form>
MY issue: The page displays well. I changed something and clicked update. The page refreshed to unchanged page, without calling get_success_url() as I expected. I checked the database, record didn't update either. I checked the template again and again but didn't find error.
Following Selcuk advice, I add print form.errors. When the editing page is display, it prints all field names as error like below:
When I update, print as:
I'm not sure what's that means.
hoping for some guidance around my below problem with displaying reverse lookup field in a template inside formsets.
Maintenance Item Model
class Maintenance_Item(CommonInfo):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, unique=True)
name_description = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
Checklist Model
class MaintenanceCheckList(CommonInfo):
CHOICES = (
('P','Compliant'),
('F','Non-Compliant'),
)
id = models.AutoField(primary_key=True)
item = models.ForeignKey(Maintenance_Item, on_delete=PROTECT, related_name='item_name')
is_compliant = models.CharField(max_length=20, choices= CHOICES, default=CHOICES[0][0])
def __int__(self):
return self.item
EDIT Form
class MaintenanceCheckListComplianceForm(forms.ModelForm):
is_compliant = forms.ChoiceField(
choices=MaintenanceCheckList.CHOICES,
widget=forms.RadioSelect,
required=False,
)
class Meta:
model = MaintenanceCheckList
fields = ('item','is_compliant',)
END EDIT
The current template
<form class="" method='post'>
{% csrf_token %}
{{ form.management_form }}
<table class="table my-0" id="dataTable">
<thead>
<tr>
<th>Maintenance Items</th>
</tr>
</thead>
<tbody>
{% for sub_form in form %}
<tr>
{% for i in sub_form.item_name.all %}
<td>Item: {{ i.name }}</p>
{% endfor %}
{{ sub_form.item|add_class:"form-select" }}<p>
</p>{{ sub_form.is_compliant }}</td>
</tr>
{% endfor %}
</table>
<div class="divider"></div>
<div class="col-md-12">
<p class='pt-sm-2'>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Currently, I have generic formset view which creates an row for each item in the Maintenance_Item which works brilliant and generates the formset view as shown.
The challenge, I have is I want to hide the ModelChoice fields (I can do that easily with a Widget), and just display the friendly name in the ModelChoice field as a simple Text Label in the template.
Note setting disabled won't work because POST ignores disabled fields (already troubleshooted using that)
I am new in Django, I'm making an item-category exercise. each item belongs to a category via a foreign key.I'm not able to understand problem in my code during submission of item detail. I'm getting an error "FOREIGN KEY constraint failed".
I wrote the code for models.py which is working fine in the admin dashboard of Django, but if same thing I'm trying to implement by HTML form page, I'm getting error.
models.py
class ColorCat(models.Model):
name = models.CharField(max_length=20, default="other")
def __str__(self):
return self.name
class ListItems(models.Model):
name = models.CharField(max_length=25, default='item')
item_cat = models.ForeignKey(ColorCat, on_delete=models.CASCADE, default=0, null=True,blank=True)
views.py
def index(request):
list = ListItems.objects.all()
cat = ColorCat.objects.all()
return render(request, 'colorlist.html', {'color': cat, 'item':list })
def colorlist(request):
new_list = ListItems
new_cate = ColorCat
if request.method=="POST":
item = str(request.POST["item"])
cat = str(request.POST["category"])
f_key = ColorCat.objects.filter(name="orange").get()
new_list(name="item").save()
new_list(item_cat=f_key.id).save()
item = ListItems.objects.all()
color = ColorCat.objects.all()
return render(request, 'colorlist.html', {"item": item, "color": color})
def addcat(request):
if request.method=="POST":
newcat = str(request.POST["name"])
ColorCat(name = newcat).save()
item = ListItems.objects.all()
color = ColorCat.objects.all()
return render(request, 'colorlist.html', {"item":item, "color":color})
colorlist.html
{% extends 'base.html'%}
{% block content%}
<h2>Welcome in color cards</h2>
<form action="addcat" method="POST">
{% csrf_token %}
<lable>add new cat<input type="text" name="name"></lable><br>
<label>submit<input type="submit"></label>
</form>
<form action="colorlist" method="post">
{% csrf_token %}
<label>new item<input type="text" name="item"></label><br>
<label>cat<input type="text" name="category"></label><br>
<label>add item<input type="submit"></label>
</form>
<!--see saved result-->
<table>
<tr>
<th>categories</th>
</tr>
{% for cat in color %}
<tr>
<td>{{cat.name}}</td>
</tr>
{% endfor %}
</table>
<table>
<tr>
<th>category item </th>
</tr>
{% for clr in color %}
{% for itm in item %}
<tr>
{% if clr.name == itm.category %}
<td>{{itm.name}}</td>
{%endif%}
</tr>
{% endfor %}
{% endfor %}
</table>
{% endblock %}
Error
IntegrityError at /color/colorlist
FOREIGN KEY constraint failed
I haven't gone allof your code - there's lots of irrelevant stuff - but I've noticed a couple of errors:
definition of ListItems model, it doesn't make sense to define a default value for field item_cat, it'll try to link the instance with a ColorCat instance with id 0 which probably doesn't exist
item_cat = models.ForeignKey(ColorCat, on_delete=models.CASCADE, null=True, blank=True)
saving a new_list - use ColorCat instance instead of its id
new_list(item_cat=f_key).save()
This is my models.py file.
class CustomerInfo(models.Model):
customer_name=models.CharField('Customer Name', max_length=50)
customer_mobile_no = models.CharField('Mobile No', null=True, blank=True,max_length=12)
customer_price=models.IntegerField('Customer Price')
customer_product_warrenty = models.CharField('Product Warrenty',null=True, blank=True,max_length=10)
customer_sell_date = models.DateTimeField('date-published', auto_now=True)
customer_product_id=models.CharField('Product ID',max_length=150,null=True, blank=True)
customer_product_name=models.CharField('Product Name', max_length=50)
customer_product_quantity=models.IntegerField('Quantity',default=1)
def __str__(self):
return self.customer_name
Now I want to search in muliple fieds like as customer_name, customer_mobile_no,customer_product_id etc. So I created views.py file
def customerPage(request):
customers = CustomerInfo.objects.all()
if request.method =="GET":
customerid = request.GET['customer_id']
try:
customers = CustomerInfo.objects.get(pk=customerid)
cus_name = CustomerInfo.objects.filter(customer_name__contains=customerid)
mobile_number = CustomerInfo.objects.filter(customer_mobile_no__contains=customerid)
return render(request, 'shop/customer.html', {"cus_name": cus_name,"mobile_number": mobile_number, "customers": 'customers', "site_name": "Moon Telecom"})
except:
return render(request, 'shop/customer.html', {"error": "Not found any info"})
return render(request, 'shop/customer.html', {'customers': customers})
and this is my html file
{% extends "shop/base.html" %}
{% block content_area %}
<div class="col-lg-4">
<div class="customer_search" >
<form action="{% url "shop:customerPage" %}" method="GET">
{% csrf_token %}
<div class="form-group">
<label for="customer_id">Id:</label>
<input type="text" class="form-control" id="customer_id" placeholder="Enter customer ID" name="customer_id">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<div class="col-lg-8 customers_info">
{% if error %}
<div class="alert alert-danger">
<strong>{{error}}</strong>
</div>
{% endif %}
{% if cus_name %}
{% for x in cus_name %}
<p>{{x.customer_name}}</p>
{% endfor %}
{% else %}
<p>nothing foung</p>
{% endif %}
{% if customers %}
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Mobile No</th>
<th>Product Name</th>
<th>Price</th>
<th>Date</th>
<th>Product ID</th>
<th>Warrenty</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{customers.customer_name}}</td>
<td>{{customers.customer_mobile_no}}</td>
<td>{{customers.customer_product_name}}</td>
<td>{{customers.customer_price}} TK</td>
<td>{{customers.customer_sell_date}}</td>
<td>{{customers.customer_product_id}}</td>
<td>{% if customers.customer_product_warrenty == '' %}
<b>No Warrenty</b>
{% else %}
<b>{{customers.customer_product_warrenty}}</b> Month
{% endif %}
</td>
</tr>
</tbody>
</table>
{% else %}
<p>nothing found</p>
{% endif %}
</div>
{% endblock %}
I got results If I use POST method and customers = CustomerInfo.objects.get(pk=customerid) When I searched one field, I have got my results but When I start multiple search query from the database. I cant get any info. I want to search multiple fields within CustomerInfo model. Also, I was trying others mehtod but not working.
You need to search using multiple fields in one query. And looking at your code, i presume that the conditions are joined using OR.
This problem can be solved using django ORM's Q object
What it allows you do is to chain multiple filtering conditions together and connect them logically.
So, if you have 3 conditions and they are logically connected as :
Condition 1 OR Condition 2 AND Condition 3 using Q you can write them as :
Q(Condition1) | Q(Conditon2) & Q(Condition2).
In your case the 3 different searches of filterings can be performed as:
filtered_customers = CustomerInfo.objects.filter( Q(pk = int(customerid)) | Q(customer_name__contains = str(customerid)) | Q(customer_mobile_no__contains = str(customerid)))
I want to add all the columns in 1 algorithm for a search. If it is possible.
Something like this:
*UPDATE * ( i have update the views.py and search_table.html )
It is only searching correctly the url field. The id and the title anything i put in those fields it will give me the entire table.
views.py
def search_table(request, pk):
table_name = Crawledtables.objects.get(id=pk)
t = create_model(table_name.name)
q = request.GET['q']
if q is not None:
query = t.objects.filter(Q(id__icontains=q) | Q(title__icontains=q) | Q(url__icontains=q))
return render(request, 'search/results_table.html', {'tbl_name': table_name,
'details': query,
'query': q})
else:
return HttpResponse("Please submit a search term!")
results_table.html
<strong> {{ tbl_name }}</strong>
<p> You searched for: <strong>{{ query }}</strong></p>
{% if details %}
<p> Found {{ details|length }}</p>
<div class="row">
<table class="table table-bordered sortable">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Url</th>
</tr>
</thead>
<tbody>
{% for lists in details %}
<tr>
<td>{{ lists.id }}</td>
<td>{{ lists.title }}</td>
<td>{{ lists.url }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p> No results found</p>
{% endif %}
{% endblock %}
search_table.html
{% if tbl_name %}
<form action="/search/{{ tbl_name.id }}/results" method="GET">
{% endif %}
<input type="text" name="q" placeholder="Id">
<input type="text" name="q" placeholder="Title">
<input type="text" name="q" placeholder="Url">
<input type="submit" value="Search">
</form>
UPDATE
models.py
def create_model(db_table):
class CustomMetaClass(ModelBase):
def __new__(cls, name, bases, attrs):
model = super(CustomMetaClass, cls).__new__(cls, name, bases, attrs)
model._meta.db_table = db_table
return model
class AllTables(models.Model):
__metaclass__ = CustomMetaClass
id = models.IntegerField(primary_key=True)
title = models.CharField(db_column='Title', blank=True, null=True, max_length=250)
url = models.CharField(db_column='Url', unique=True, max_length=250, blank=True,
null=True)
created_at = models.DateTimeField(db_column='Created_at')
return AllTables
Q objects are used to make complex logical queries.
use in syntax: AND (&) and OR (|)
from django.db.models import Q
t.objects.filter(Q(id__icontains=q_id) | Q(title__icontains=q_title) | Q(url__icontains=q_url))