I have a question, what happens is that I have a formset and an empty_form (in the same HTML); I have them to do some calculations, for the empty_form I already managed to extract the ID and do operations but not for the formset, and that is that my main problem is that they have the different ID, for example for the formset is like this:
id_form-0-quantity
and for the empty_form it is:
id__form-1-quantity (one more underscore)
but with that different ID I have to make some changes in JS, which I don't want to do because I'm very new in JS and possibly messing up the code more. Is there a way to change the formset prefix to look like this: id__form-0-quantity?;
I used the following line:
formset = ParteFormSet(request.POST, request.FILES, prefix='__form')
But absolutely nothing happens
views
def create_Presupuestos(request):
extra_forms = 1
ParteFormSet = formset_factory(PresupuestosParteForm, extra=extra_forms, max_num=20)
presupuestosclientesform=PresupuestosClientesForm(request.POST or None)
presupuestosvehiculosform=PresupuestosVehiculosForm(request.POST or None)
presupuestosparteform=PresupuestosParteForm(request.POST or None)
presupuestosmanoobraform=PresupuestosManoObraForm(request.POST or None)
presupuestospagosform=PresupuestosPagosForm(request.POST or None)
if request.method == 'POST':
formset = ParteFormSet(request.POST, request.FILES, prefix='__form')
if formset.is_valid():
presupuestosclientesform.save()
return redirect('presupuestos:index')
else:
formset = ParteFormSet()
return render(request,'Presupuestos/new-customer.html',{'presupuestosclientesform':presupuestosclientesform,'presupuestosvehiculosform':presupuestosvehiculosform,'presupuestosparteform':presupuestosparteform,'presupuestosmanoobraform':presupuestosmanoobraform,'presupuestospagosform':presupuestospagosform,'formset':formset})
HTML
<table class="table table-bordered table-nowrap align-middle" id="childTable1">
<thead class="table-info">
<tr>
<th scope="col">Quantity</th>
<th scope="col">Unit Price</th>
</thead>
<tbody>
{{ formset.management_form }}
{% for form in formset %}
<div class="part-form">
<tr>
<td>
{{form.quantity}}
<!-- <input type="text" name="parts_quantity" class="form-control input-new-customer-quantity" />-->
</td>
<td>
{{form.unit_price}}
<!-- <input type="text" name="parts_unit_price" class="form-control input-new-customer-unit-price" />-->
</td>
</tr>
</div>
{% endfor %}
</tbody>
</table>
<div class="part-form table-responsive" id="empty-row">
<table class="table table-bordered table-nowrap align-middle">
<tr>
<td>{{formset.empty_form.quantity}}</td>
<td>{{formset.empty_form.unit_price}}</td>
</tr>
</table>
</div>
You should also include the prefix in the case of a GET request, otherwise it will not prefix that form when you load the page for the first time:
def create_Presupuestos(request):
extra_forms = 1
ParteFormSet = formset_factory(PresupuestosParteForm, extra=extra_forms, max_num=20)
presupuestosclientesform=PresupuestosClientesForm(request.POST or None)
presupuestosvehiculosform=PresupuestosVehiculosForm(request.POST or None)
presupuestosparteform=PresupuestosParteForm(request.POST or None)
presupuestosmanoobraform=PresupuestosManoObraForm(request.POST or None)
presupuestospagosform=PresupuestosPagosForm(request.POST or None)
if request.method == 'POST':
formset = ParteFormSet(request.POST, request.FILES, prefix='__form')
if formset.is_valid():
presupuestosclientesform.save()
return redirect('presupuestos:index')
else:
# prefix in case of a GET 🖟
formset = ParteFormSet(prefix='__form')
return render(request,'Presupuestos/new-customer.html',{'presupuestosclientesform':presupuestosclientesform,'presupuestosvehiculosform':presupuestosvehiculosform,'presupuestosparteform':presupuestosparteform,'presupuestosmanoobraform':presupuestosmanoobraform,'presupuestospagosform':presupuestospagosform,'formset':formset})
Related
I am tasked with making a shopping crud project with models Products,categories,sub_categories,size,colors. Categories and subcategories are connected via foreign keys and I am using SERAILIZERS.the problem is that when I try to insert the data into sub Categories it doesnt come in both the database and the webpage
I also tried value = "{{c.category_name}}" as well in select dropdown as well
below are the models
class Categories(models.Model):
category_name = models.CharField(max_length=10)
category_description = models.CharField(max_length=10)
isactive = models.BooleanField(default=True)
class SUBCategories(models.Model):
category_name = models.ForeignKey(Categories,on_delete=models.CASCADE)
sub_categories_name = models.CharField(max_length=20)
sub_categories_description = models.CharField(max_length=20)
isactive = models.BooleanField(default=True)
show and insert function of sub_categories
def show_sub_categories(request):
showsubcategories = SUBCategories.objects.filter(isactive=True)
#print(showsubcategories)
serializer = SUBCategoriesSerializer(showsubcategories,many=True)
print(serializer.data)
return render(request,'polls/show_sub_categories.html',{"data":serializer.data})
def insert_sub_categories(request):
if request.method == "POST":
insertsubcategories = {}
insertsubcategories['sub_categories_name']=request.POST.get('sub_categories_name')
insertsubcategories['sub_categories_description']=request.POST.get('sub_categories_description')
form = SUBCategoriesSerializer(data=insertsubcategories)
if form.is_valid():
form.save()
print("hkjk",form.data)
messages.success(request,'Record Updated Successfully...!:)')
print(form.errors)
return redirect('sub_categories:show_sub_categories')
else:
print(form.errors)
else:
insertsubcategories = {}
form = SUBCategoriesSerializer(data=insertsubcategories)
category_dict = Categories.objects.filter(isactive=True)
category = CategoriesSerializer(category_dict,many=True)
hm = {'context': category.data}
if form.is_valid():
print(form.errors)
return render(request,'polls/insert_sub_categories.html',hm)
html of the insert page and show page respectively
<td>category name</td>
<td>
<select name="category_name" id="">
{% for c in context %}
<option value="{{c.id}}">{{c.category_name}}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td>sub categories Name</td>
<td>
<input type="text" name="sub_categories_name" placeholder="sub categories ">
</td>
</tr>
<tr>
<td>Sub categories Description</td>
<td>
<textarea name="sub_categories_description" id="" cols="30" rows="10">
</textarea>
</td>
</tr>
<tr>
<td>
<input type="submit" value="Insert" />
</td>
<td>
{% if messages %}
{% for mess in messages %}
<b style="color:green;">{{mess}}</b>
{% endfor %}
{% endif %}
</td>
<tbody>
<tr>
<td><b>{{result.sub_categories_name}}</b></td>
<td><b>{{result.sub_categories_description}}</b></td>
<td style="position: relative;left:50px;">
<a href="sub_categories/edit_sub_categories/{{result.id}}">
<button class="btn btn-primary">
<i class="fa-solid fa-pen-to-square">EDIT</i>
</button>
</a>
</td>
<td>
<a href="{% url 'sub_categories:delete_sub_categories' result.id %}" onclick="return confirm('Are You Sure you want to delete?')">
<button class="btn btn-danger">
<i class="fa-solid fa-trash">DELETE</i>
</button>
</a>
</td>
</tr>
</tbody>
categories and sub categories serializer
class CategoriesSerializer(serializers.ModelSerializer):
class Meta:
model = Categories
fields = "__all__"
extra_kwargs = {'category_name': {'required': False}}
class SUBCategoriesSerializer(serializers.ModelSerializer):
class Meta:
model = SUBCategories
fields = "__all__"
where am I going wrong in the code?
Try this out and let me know, a few changes you'd require
def insert_sub_categories(request):
if request.method == "POST":
form = SUBCategoriesSerializer(data=request.POST)
if form.is_valid():
form.save()
messages.success(request, "Record Updated Successfully...!:)")
return redirect("sub_categories:show_sub_categories")
category_dict = Categories.objects.filter(isactive=True)
category = CategoriesSerializer(category_dict, many=True)
hm = {"context": category.data}
return render(request, "polls/insert_sub_categories.html", hm)
Form part
<form method="POST">
{% csrf_token %}
<table>
<thead>
<tr>
<td>category name</td>
<td>
<select name="category_name" id="">
{% for c in context %}
<option value="{{c.id}}">{{c.category_name}}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td>sub categories Name</td>
<td>
<input type="text" name="sub_categories_name" placeholder="sub categories ">
</td>
</tr>
<tr>
<td>Sub categories Description</td>
<td>
<textarea name="sub_categories_description" id="" cols="30" rows="10">
</textarea>
</td>
</tr>
<tr>
<td>Active</td>
<td>
<input type="checkbox" name="isactive" value="true" checked>
</td>
</tr>
<tr>
<td>
<input type="submit" value="Insert" />
</td>
<td>
{% if messages %}
{% for mess in messages %}
<b style="color:green;">{{mess}}</b>
{% endfor %}
{% endif %}
</td>
</tr>
</thead>
</table>
<button class="btn btn-success">Go To Home</button>
</form>
model
class SUBCategories(models.Model):
category_name = models.ForeignKey(Categories, on_delete=models.CASCADE)
sub_categories_name = models.CharField(max_length=20)
sub_categories_description = models.CharField(max_length=20)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.category_name.category_name
This error occurs because there is a chance in your function view, that it does not return proper Response or Redirect object. If you send POST request, but the form is not valid, then it will not return anything.
def insert_sub_categories(request):
if request.method == "POST":
...
if form.is_valid():
...
return redirect('sub_categories:show_sub_categories')
else:
print(form.errors)
# HERE YOU MISS REDIRECT/RENDER
else:
...
return render(request,'polls/insert_sub_categories.html',hm)
Also you don't pass SUBCategories.category_name to your serializer. It's required field, so it will never be valid without it. You may try form = SUBCategoriesSerializer(request.POST) instead of adding values one by one.
I am creating a small application where I am able to add / modify / delete / view a member.
def member_edit(request,member_id):
MemberForm = modelform_factory(Member, fields=('employee_id', 'employee_name'))
if request.method == 'POST':
member = MemberForm(request.POST)
if member.is_valid():
member.save()
return HttpResponseRedirect(reverse("members:member_view"))
else:
member = get_object_or_404(Member, pk=member_id)
return render(request, 'members/member_edit.html', {'member': member})
I notice that instead of being able to edit all the fields become in display mode.
<form action="" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<table>
<tr>
<th> <label for="{{ member.employee_id.id_for_label }}">Employee id:</label> </th>
<td> <input type="text" value = {{ member.employee_id }} /> </td>
<td> {{ member.employee_id.errors }} </td>
</tr>
<tr>
<th> <label for="{{ member.employee_name.id_for_label }}">Employee Name:</label> </th>
<td> <input type="text" value = {{member.employee_name }} /></td>
<td> {{ member.employee_name.errors }} </td>
</tr>
</table>
<input type="submit" value="Update">
If I change the member_edit function to this, it works but I don't have any data to change(obviously) :
def member_edit(request,member_id):
MemberForm = modelform_factory(Member, fields=('employee_id', 'employee_name'))
if request.method == 'POST':
member = MemberForm(request.POST)
if member.is_valid():
member.save()
return HttpResponseRedirect(reverse("members:member_view"))
else:
member = MemberForm() # change made only here
return render(request, 'members/member_edit.html', {'member': member})
What am I missing here ?
I think you need to pass the member instance to the form.
from django.shortcuts import get_object_or_404
def member_edit(request, member_id):
MemberForm = modelform_factory(Member, fields=('employee_id', 'employee_name'))
if request.method == 'POST':
instance = get_object_or_404(Member, id=member_id)
member = MemberForm(request.POST, instance=instance)
if member.is_valid():
member.save()
return HttpResponseRedirect(reverse("members:member_view"))
else:
member = MemberForm() # change made only here
return render(request, 'members/member_edit.html', {'member': member})
Good morning. I am having an issue trying to remove a client from an assigned bed. I created a one-item form called "RoomUpdate" that will allow a user to add a client to a bed that is empty via a dropdown through a ModelChoiceField.
When the bed is full, it does not allow the access to the drop down, instead, I have a link that states "remove client." What I want to happen is when I click that button, it assigns the default value of None to that bed in that room.
What's tricky, at least to my new-ish to Django mind, is how I do this through multiple tables. Having looked for multiple answers and tried different things, I know I've lost track of what I'm doing so I definitely could use some help.
models.py
class Room(models.Model):
room_id = models.AutoField(primary_key=True)
room_number = models.CharField(max_length=5)
shelter_id = models.ForeignKey(Shelter)
max_occupancy = models.CharField(max_length=3)
floor_location = models.CharField(max_length=3)
def __str__(self):
return self.room_number
class Bed(models.Model):
bed_id = models.AutoField(primary_key=True)
room_id = models.ForeignKey(Room, related_name='beds')
bed_size = models.ForeignKey(BedSize)
client_assigned = models.ForeignKey(Clients, null=True, blank=True, default=None)
forms.py
class RoomUpdate(forms.ModelForm):
client_assigned = forms.ModelChoiceField(queryset=Clients.objects.all(), required=False)
#def __init__(self, *args, **kwargs):
#super(RoomUpdate, self).__init__(*args, **kwargs)
#self.fields['client_assigned'].choices.insert(0, ('','---------' ) )
class Meta:
model = Room
fields = ( 'client_assigned', )
views.py
def room_update(request, pk, template_name='shelter/room_edit.html'):
rooms = get_object_or_404(Room, pk=pk)
form = RoomUpdate(request.POST or None, instance=rooms)
beds = Bed.objects.filter(room_id=pk)
if form.is_valid():
form.save()
return redirect('/shelter/')
return render(request, template_name, {'form': form, 'rooms': rooms, 'beds':beds,})
def remove_client(request, pk):
rooms = get_object_or_404(Room, pk=pk)
bed = Bed.objects.filter(room_id=pk)
form = RoomUpdate(request.POST)
template_fail = 'clients/invalid_permissions.html'
if request.method=='POST':
if form.is_valid():
bed.objects.update(client_assigned=None)
bed.save()
else:
return redirect(request, template_fail)
return render_to_response(request, {'rooms': rooms, 'bed': bed})
template
<form action="" method="POST">
{% csrf_token %}
<div class="room box-shadow">
<h4>Room {{ rooms.room_number }}</h4>
<table>
{% for i in rooms.beds.all %}
<tr>
<td>Bed ID: </td>
<td>{{i.bed_id }}</td>
</tr>
<tr>
<td>Bed Size: </td>
<td>{{i.bed_size }}</td>
</tr>
<tr>
<td valign="top">Client: </td>
<td>
{% if i.client_assigned %}
{{ i.client_assigned }}
<br \>
Remove Client
{% else %}
{{ form.client_assigned }}
{% endif %}
</td>
</tr>
<tr>
<td colspan="2">
<hr class="style-two" />
</td>
</tr>
{% endfor %}
<tr>
<td><input type="submit" value="Submit" /></td>
<td></td>
</tr>
</table>
</div>
</form>
I've been playing around with this a bit and making some sort of progress. If I change the url from the same as the edit, I get it to work in that it deletes from the table and redirects the user to a new page.
I would prefer it not redirect the user to a new page, but rather, update the page that's there.
Thoughts?
The new view looks like this:
def remove_client(request, pk, template_name='shelter/test.html'):
bed = Bed.objects.filter(bed_id=pk).update(client_assigned=None)
return render(request, template_name, { 'bed':bed })
Further diving into this, I found a solution I rather like and actually works in a way I wanted but couldn't figure out. Instead of focusing on the room, I realized that I needed to focus on the smaller container -- the bed -- and since it can move around, it would be the better choice.
Currently, this functionality allows me to move beds to different rooms, remove clients by selecting the '----' selector, and allows me to add clients.
So here is the answer I came up with:
forms.py
class RoomUpdate(forms.ModelForm):
bed_id = forms.CharField()
room_id = forms.ModelChoiceField(queryset=Room.objects.all())
bed_size = forms.ModelChoiceField(queryset=BedSize.objects.all(), required=False)
client_assigned = forms.ModelChoiceField(queryset=Clients.objects.all(), required=False)
class Meta:
model = Bed
fields = ('bed_id', 'client_assigned', 'room_id', 'bed_size' )
views.py
def room_update(request, pk, template_name='shelter/room_edit.html'):
beds = get_object_or_404(Bed,pk=pk)
form = RoomUpdate(request.POST or None, instance=beds)
if form.is_valid():
form.save()
return redirect('/shelter/')
return render(request, template_name, {'form': form, 'beds':beds,})
room_edit.html
<form action="" method="POST">{% csrf_token %}
<div class="room box-shadow">
<h4>Room </h4>
<table>
<tr>
<td>Room: </td>
<td>{{ form.room_id }}</td>
</tr>
<tr>
<td>Bed ID: </td>
<td>{{ form.bed_id }}</td>
</tr>
<tr>
<td>Bed Size: </td>
<td>{{ form.bed_size }}</td>
</tr>
<tr>
<td valign="top">Client: </td>
<td>{{ form.client_assigned }}</td>
</tr>
<tr>
<td colspan="2"><hr class="style-two" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit" /></td>
<td></td>
</tr>
</table>
</div>
</form>
I would like to add data filled into database and output it. But i have no idea where is wrong because my data was't saved into database at all. In views.py, Scholarship is just one scholarship object, LScholarship is displaying all the data in Scholarship. I have similar code for other models and views but i have no idea what i did wrong in here, making the data can't be saved into database. Could anyone please advice me where am i wrong
add_remove_scholarship.html
<div align="center" >
<form method="POST" onsubmit="return validation()" action="">
{% csrf_token %}
{{ form.errors }}
<p>Upload File: {{scholarship.doc}} <input id="doc" type="text" name="doc"> </p>
<p>Faculty: {{scholarship.faculty}} <input id="faculty" type="text" name="faculty"> </p>
<p>Opening date: {{scholarship.openDate}} <input id="odate" type="date" name="openDate"> </p>
<p>Closing date: {{scholarship.closeDate}} <input id="edate" type="text" name="closeDate"> </p>
<input type="submit" name="AddScholarship" value="Add Scholarship" >
</form>
</div>
<br></br>
<button id="button" type="button">Delete Selected Scholarship</button>
<br></br>
<form method="POST" action="">
{% csrf_token %}
<table id="example" class="display" cellspacing="0" width="100%" border="1.5px">
<tr align="center">
<th> Scholarship </th>
<th> Faculty </th>
<th> Open Date </th>
<th> Close Date </th>
</tr>
{% for item in query_results %}
<tr align="center">
<td>{{item.doc}}</td>
<td>{{item.faculty}}</td>
<td>{{item.openDate}}</td>
<td>{{item.closeDate}}</td>
</tr>
{% endfor %}
</table>
</form>
models.py
#consists of all the details of the scholarship under the 'Add/Remove
Scholarship'
class Scholarship(models.Model):
doc = models.TextField("Doc", max_length=1000)
faculty = models.TextField("Faculty", max_length=1000)
openDate = models.DateField("Opening Date", max_length=8)
closeDate = models.TextField("CLosing Date", max_length=18)
def __str__(self):
return self.doc
#consists of all the details of the scholarship under the 'Add/Remove
Scholarship'
class LScholarship(models.Model):
scholarship = models.ForeignKey(Scholarship, on_delete=models.CASCADE)
views.py
def scholarship(request):
if request.method == "POST":
form = ScholarshipForm(request.POST)
if form.is_valid():
scholarship = form.save(commit=False)
scholarship.save()
else:
form = ScholarshipForm()
return render(request, 'hrfinance/add_remove_scholarship.html', {'form': form})
def lscholarship(request):
query_results = Scholarship.objects.all()
data={'query_results':query_results}
return render(request, 'hrfinance/add_remove_scholarship.html', data)
class ScholarshipForm(forms.ModelForm):
class Meta:
model = Scholarship
fields = '__all__'
You are using two views to render a single template.
You can merge your views into a single one and maybe reduce the logic.
If I have understood your problem correctly you could use your view more like this,
def scholarship(request, id=None):
query_results = []
if request.method == "POST":
form = ScholarshipForm(request.POST)
if form.is_valid():
scholarship = form.save(commit=False)
scholarship.save()
else:
form = ScholarshipForm()
id = request.GET.get('scholarship')
query_results = Scholarship.objects.all()
data = {
'query_results':query_results,
'form': form,
}
return render(request, 'hrfinance/add_remove_scholarship.html', data)
In your template,
<div align="center" >
<form method="POST" onsubmit="return validation()" action="">
{% csrf_token %}
{{ form.errors }}
<p>Upload File: {{ form.doc }}</p>
<p>Faculty: {{ form.faculty }} </p>
<p>Opening date: {{ form.startDate }} </p>
<p>Closing date: {{ closeDate }} </p>
<button type="submit" name="AddUser" value="Add Scholarship" onclick="add()" >Add Scholarship</button>
</form>
</div>
<table id="example" class="display" cellspacing="0" width="100%" border="1.5px">
<tr align="center">
<th> Scholarship </th>
<th> Faculty </th>
<th> Open Date </th>
<th> Close Date </th>
</tr>
{% for item in query_results %}
<tr align="center">
<td>{{item.doc}}</td>
<td>{{item.faculty}}</td>
<td>{{item.openDate}}</td>
<td>{{item.closeDate}}</td>
</tr>
{% endfor %}
</table>
I have a problem: I want to make checkboxes of each line of table:
<form action="" method="post">
{% csrf_token %}
<table>
<thead>
<tr>
<th>cb</th>
<th width="150">first_col</th>
<th>sec_col</th>
<th width="150">third_col</th>
</tr>
</thead>
<tbody>
{% for i in list %}
<tr>
<td><input type="checkbox" name="choices" value="{{i.id}}"></td>
<td>{{ i.created_date}}</td>
<td> {{ host }}/{{i}}/ </td>
<td>{{i.number_of_clicks}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit" name="delete" class="button">Del</button>
</form>
And in the def I make next in order to check if it works:
if 'delete' in request.POST:
for item in request.POST.getlist('choices'):
print (item)
But it does not print anything... What do i do wrong? Or can you help me to write correct handler of checkboxes?
First you should check for request.method == 'POST' rather than for the submit button name in request.POST. Though, that shouldn't be the problem why you don't see anything. From what you posted I don't know what's not working but here's an example that shows how you could achive what you want. It assumes your template is in test.html:
# This is just a dummy definition for the type of items you have
# in your list in you use in the template
import collections
Foo = collections.namedtuple('Foo', ['id', 'created_date', 'number_of_clicks'])
def test(request):
# check if form data is posted
if request.method == 'POST':
# simply return a string that shows the IDs of selected items
return http.HttpResponse('<br />'.join(request.POST.getlist('choices')))
else:
items = [Foo(1,1,1),
Foo(2,2,2),
Foo(3,3,3)]
t = loader.get_template('test.html')
c = RequestContext(request, {
'list': items,
'host': 'me.com',
})
return http.HttpResponse(t.render(c))