I want the ability to update records in a table format so that I can quickly make updates. I am close to figuring this out, but form.valid() is still returning False.
My model:
class Actions(models.Model):
meeting = models.ForeignKey(Meeting, on_delete=models.CASCADE)
dateAdded = models.DateTimeField(default = timezone.now, editable = False)
dateComplete = models.DateTimeField(null=True, blank=True)
action = models.TextField(max_length=1000,)
responsibility = models.ForeignKey(staff, on_delete=models.CASCADE, blank=True,null = True,)
complete = models.BooleanField(default = False)
My view:
def actionItemsView(request):
ActionFormSet = modelformset_factory(Actions, fields=('action', 'responsibility','complete','meeting','dateComplete'),max_num=1)
if request.method == "POST":
action_formset = ActionFormSet(request.POST, request.FILES,queryset=Actions.objects.filter())
for action_form in action_formset:
print(action_form.errors)
if action_form.is_valid():
action = action_form.save()
return HttpResponseRedirect('/saved!/')
else:
formset = ActionFormSet(queryset=Actions.objects.filter(complete = False))
return render(request, 'action_items.html', {'formset': formset})
My template:
<table class="table table-hover table-sm">
<tr>
<th>decision</th>
<th>responsibility</th>
<th>complete?</th>
<th>meeting</th>
<th>date complete</th>
<th>submit</th>
</tr>
{%for form in formset%}
<form method="post" enctype= multipart/form-data>
<tr>
{{ formset.management_form }}
{{ form.management_form }}
{% csrf_token %}
<td>{{ form.action }}</td>
<td>{{ form.responsibility }}</td>
<td>{{ form.complete }}</td>
<td>{{ form.meeting }}</td>
<td>{{ form.dateComplete }}</td>
<td><button type="submit">Save</button></td>
</tr>
</form>
{% endfor %}
</table>
When I run this, the template is rendered exactly how I would expect, but when I make any changes to an item and hit submit, it throws The view meetings.views.actionItemsView didn't return an HttpResponse object. It returned None instead.
Because form.valid() is False
form.errors is returning:
<ul class="errorlist"><li>id<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
<ul class="errorlist"><li>action<ul class="errorlist"><li>This field is required.</li></ul></li><li>meeting<ul class="errorlist"><li>This field is required.</li></ul></li><li>id<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
<ul class="errorlist"><li>action<ul class="errorlist"><li>This field is required.</li></ul></li><li>meeting<ul class="errorlist"><li>This field is required.</li></ul></li><li>id<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
But I can see in the template that each record has a meeting assigned to it in the dropdown...
The view meetings.views.actionItemsView didn't return an HttpResponse object. It returned None instead.
Given this is the error, it's saying that you are not returning any HTTPRESPONSE, which is true since you don't have any return statements if it's a POST request.
if request.method == "POST":
action_formset = ActionFormSet(request.POST, request.FILES,queryset=Actions.objects.filter())
for action_form in action_formset:
print(action_form.errors)
if action_form.is_valid():
action = action_form.save()
All methods in views.py are required to return an HTTPRESPONSE, so simply try to add any kind of HTTP response in there and it should solve your problem.
Related
I am not able to GET a variable from a template into another view.
I have a table with some records. Each row has a button which I would like to click and retrieve more details about the record in another page. I have been looking online but I cannot figure out how I should implement this. Everything I have tried either crashed or gave back None.
list.html
{% for trainee in trainees_list %}
<tr>
<td>{{ trainee.last_name }}</td>
<td>{{ trainee.first_name }}</td>
<td><a class="btn btn-primary" href="{% url 'traineedetails'%}" value="{{ trainee.pk }}" >View</a></td>
</tr>
{% endfor %}
view.py
def traineedetails(request):
if request.method == 'GET':
trainee_details = request.POST.get('trainee.pk')
print(trainee_details)
return render(request, 'trainee_details.html')
def listoftrainees(request):
trainees_list = UserTraining.objects.all()
return render_to_response('list.html', {'trainees_list': trainees_list})
url.py
urlpatterns = [
path('traineedetails', views.traineedetails, name='traineedetails'),
path('listoftrainees', views.listoftrainees, name='listoftrainees'),
]
form.py
class UserTrainingForm(forms.ModelForm):
scope_requirements = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=microscopes.MICROSCOPES)
class Meta:
model = UserTraining
fields = (
'first_name',
'last_name',
)
model.py
class UserTraining(models.Model):
first_name = models.CharField('first name', max_length = 100)
last_name = models.CharField('last name', max_length = 100)
I would like to be able to click on the button in the row of the table and retrive more information about the record.
You pass the value directly in the url like : traineedetails/<pk>
In the template:
{% for trainee in trainees_list %}
<tr>
<td>{{ trainee.last_name }}</td>
<td>{{ trainee.first_name }}</td>
<td><a class="btn btn-primary" href="{% url 'traineedetails' trainee.pk%}">View</a></td>
</tr>
{% endfor %}
Edit your urls.py:
path('traineedetails/<pk>', views.traineedetails, name='traineedetails'),
Then you can retrieve it in your view like this:
from django.shortcuts import get_object_or_404
def traineedetails(request, pk):
if request.method == 'GET':
#try to get your objet or throw a 404 error
trainee = get_object_or_404(UserTraining, pk=pk)
#pass it back to the template
return render(request, 'trainee_details.html',{'trainee':trainee})
I have a table in my models which the stocks are saving in it and its name is Stocks
this table is desplayed in a template and i want to put a checkbox beside each row to save the checked row in another table of the model
here ismy model.py :
class Stocks(models.Model):
user=models.ForeignKey(User, null=True)
name=models.CharField(max_length=128,verbose_name=_('stockname'))
number=models.CharField(blank=True,null=True,max_length=64,verbose_name=_('number'))
brand=models.CharField(max_length=64, validators=[
RegexValidator(regex='^[A-Z]*$',message=_(u'brand must be in Capital letter'),)]
,verbose_name=_('brand'))
comment=models.CharField(blank=True,null=True,max_length=264,verbose_name=_('comment'))
price=models.PositiveIntegerField(blank=True,null=True,verbose_name=_('price'))
date=models.DateTimeField(auto_now_add = True,verbose_name=_('date'))
confirm=models.CharField(choices=checking,max_length=12,verbose_name=_('confirmation'), default=_('pending'))
def __str__(self):
return str(self.id)
class Meta:
verbose_name=_('Stock')
verbose_name_plural=_('Stocks')
def get_absolute_url(self):
return reverse('BallbearingSite:mystocks' )
class SellerDesktop(models.Model):
seller=models.OneToOneField(User, related_name='seller', blank=True, null=True)
buyer=models.OneToOneField(User, related_name='buyer', blank=True, null=True)
stock=models.ForeignKey(Stocks, related_name='stocktoseller', blank=True, null=True)
def __str__(self):
return str(self.seller) + '-' + str(self.buyer)
class Meta:
verbose_name=_('SellerDesktop')
verbose_name_plural=_('SellerDesktop')
and the Template :
<form method="post">
{% csrf_token %}
<table id="example" class="table table-list-search table-responsive table-hover table-striped" width="100%">
{% for item in myst %}
<td><input type="checkbox" name="sendtoseller" value="{{ item.id }}"></td>
<td>{{ item.user.profile.companyname}}</td>
<td>{{ item.name }}</td>
<td>{{ item.brand }}</td>
<td>{{ item.number }}</td>
<td>{{ item.pasvand }}</td>
<td>{{ item.comment }}</td>
<td>{{ item.price }}</td>
<td>{{ item.date|timesince }}</td>
</tr>
{% endfor %}
</table>
<div style="text-align: center; margin-top:0.5cm; margin-bottom:1cm;">
<input type="submit" name="toseller" value="Submit to seller " style="color:red; width:100%;"/>
</div>
</form>
and the view :
def allstocks_view(request):
if request.method=='POST':
tosave = request.POST.getlist('sendtoseller')
stockid=Stocks.objects.filter(id=tosave)
SellerDesktop.objects.create(buyer=request.user,stock=stockid)
stocks_list=Stocks.objects.all().filter(confirm=_('approved') ).order_by('-date')
#paginating for table
page = request.GET.get('page', 1)
paginator = Paginator(stocks_list, 15)
try:
myst = paginator.page(page)
except PageNotAnInteger:
myst = paginator.page(1)
except EmptyPage:
myst = paginator.page(paginator.num_pages)
context={
'allstocks':stocks_list,
'myst':myst,
}
return render(request,'BallbearingSite/sellerstocks.html',context)
this error was showed up
TypeError at /sellerstocks/
int() argument must be a string, a bytes-like object or a number, not 'list'
when i changed the code to :
stockid=Stocks.objects.filter(id=tosave[0])
this error was showed up:
ValueError at /sellerstocks/
Cannot assign "[]": "SellerDesktop.stock" must be a "Stocks" instance.
How can i insert the selected rows into new table?
the error :
Cannot assign must be a "" instance.
was gone when i changed :
Stocks.objects.filter(id=tosave[i])
to :
Stocks.objects.get(id=tosave[i])
I have a shipment_details form where have some information about shipment and all item in that order of the shipments. There is two model information one Shipment another is Items model. I want to update all Marco Item Shipped value using the checkbox( see the form view pics).
here is my form view
http://imgur.com/a/dcNZE
Here is my forms.py where I linked up checkbox to Items is_shipped field and this value show in the view using {{form_status.as_p}}.
forms.py
class ShipmentStatus(forms.CheckboxInput):
input_type = 'checkbox'
class ShipmentStatusForm((forms.ModelForm)):
class Meta:
model = Items
fields = ['is_shipped']
widgets = {
'is_shipped': ShipmentStatus(),
}
Here is my view model
shipment_detail.html
{% extends "_dashboardlayout.html" %}
{% block content %}
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h2 class="page-header">Shipment Details</h2>
</div>
<div class="col-md-12">
<form method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<table class="table table-striped">
<tr>
<th>Item No</th>
<th>SKU</th>
<th>Quantity</th>
<th>Price</th>
<th>Marco Item</th>
<th>Marco Item Shipped</th>
</tr>
{% for item in items_queryset %}
<tr>
<td>{{ item.item_no }}</td>
<td>{{ item.sku }}</td>
<td>{{ item.requested_quantity }}</td>
<td>{{ item.price }}</td>
<td>{{ item.is_send }}</td>
<td>{{ form_status.as_p }}</td>
</tr>
{% endfor %}
</table>
<input type="submit" value="Save">
</form>
</div>
</div>
<!-- /.row -->
</div>
{% endblock %}
Here is my control py file
def shipment_detail(request, order_id=None):
order_queryset = Order.objects.get(order_id=order_id)
customer_queryset = Customer.objects.all()
address_queryset = Address.objects.all()
items_queryset = Items.objects.filter(order_id=order_id).order_by('item_no')
shipment_queryset = Shipment.objects.filter(order_id=order_id)
# if there is no shipment data then generate shipment details for the Order
if not shipment_queryset:
form = ShipmentForm(request.POST or None)
form_status = ShipmentStatusForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.order_id = order_queryset
order_queryset.save()
instance.save()
# save item status
if form_status.is_valid():
instance = form_status.save(commit=False)
instance.save()
context = {
"form": form,
"form_status": form_status,
"order_queryset": order_queryset,
"customer_queryset": customer_queryset,
"address_queryset": address_queryset,
"items_queryset": items_queryset,
}
return render(request, "shipment_detail.html", context)
# if there is already data then updated the shipment details for the Order
else:
instance = get_object_or_404(Shipment, order_id=order_id)
form = ShipmentForm(request.POST or None, instance=instance)
if form.is_valid():
instance = form.save(commit=False)
instance.order_id = order_queryset
# updated order is_shipped field according to ship_status
if instance.status == True:
order_queryset.is_shipped = True
if instance.status == False:
order_queryset.is_shipped = False
# updated order is_completed field according to shipment is_complete field
if instance.is_complete == True:
order_queryset.is_completed = True
if instance.is_complete == False:
order_queryset.is_completed = False
order_queryset.save()
instance.save()
print "form status"
# updated item is_shipped field
instance_status = get_list_or_404(Items, order_id=order_id)
for instance in instance_status:
form_status = ShipmentStatusForm(request.POST, instance=instance)
if form_status.is_valid():
instance = form_status.save(commit=False)
instance.save()
context = {
"form": form,
"instance": instance,
"form_status": form_status,
"order_queryset": order_queryset,
"customer_queryset": customer_queryset,
"address_queryset": address_queryset,
"items_queryset": items_queryset,
}
return render(request, "shipment_detail.html", context)
Here problem is when click all the Marco Item Shipped true or false its save value properly but if I click one false another true then it doesn't save value.
One way to do this is use pk of an object as value of check box
<input type="checkbox" value='{{item.id}}'
name='for_action' id='for_action' >
, You can get list of these pk in your views using request.POST.getlist('for_action')
Here You Go!!
HTML:
<div class="col-lg-12">
<h2 class="page-header">Shipment Details</h2>
</div>
<div class="col-md-12">
<form method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<table class="table table-striped">
<tr>
<th>Item No</th>
<th>SKU</th>
<th>Quantity</th>
<th>Price</th>
<th>Marco Item</th>
<th>Marco Item Shipped</th>
</tr>
{% for item in items_queryset %}
<tr>
<td>{{ item.item_no }}</td>
<td>{{ item.sku }}</td>
<td>{{ item.requested_quantity }}</td>
<td>{{ item.price }}</td>
<td>{{ item.is_send }}</td>
<td><input type="checkbox" value='{{item.id}}'
name='for_action' id='for_action' ></td>
</tr>
{% endfor %}
</table>
<input type="submit" value="Save">
</form>
</div>
</div>
<!-- /.row -->
{% endblock %}
views.py
def shipment_detail(request, order_id=None):
#########
# save item status
list_of_id_for_action = request.POST.getlist('for_action')
list_of_obj = Items.objects.filter(pk__in=list_of_id_for_action)
list_of_obj.update(is_shipped=True)
######
context = {
"form": form,
"instance": instance,
"form_status": form_status,
"order_queryset": order_queryset,
"customer_queryset": customer_queryset,
"address_queryset": address_queryset,
"items_queryset": items_queryset,
}
Hope this helps
i'm trying to use model formsets with Django. When i load forms template, i see that it's filled-up with previous values. Is there a caching mechanism that i should stop, or what?
Thanks for your help, here is my code:
models.py
class FooModel( models.Model ):
a_field = models.FloatField()
b_field = models.FloatField()
def __unicode__( self ):
return self.a_field
forms.py
from django.forms.models import modelformset_factory
FooFormSet = modelformset_factory(FooModel)
views.py
def foo_func(request):
if request.method == 'POST':
formset = FooFormSet(request.POST, request.FILES, prefix='foo_prefix' )
if formset.is_valid():
formset.save()
return HttpResponseRedirect( '/true/' )
else:
return HttpResponseRedirect( '/false/' )
else:
formset = FooFormSet(prefix='foo_prefix')
variables = RequestContext( request , { 'formset':formset , } )
return render_to_response('footemplate.html' , variables )
template:
<form method="post" action=".">
{% csrf_token %}
<input type="submit" value="Submit" />
<table id="FormsetTable" border="0" cellpadding="0" cellspacing="0">
<tbody>
{% for form in formset.forms %}
<tr>
<td>{{ form.a_field }}</td>
<td>{{ form.b_field }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ formset.management_form }}
</form>
The main problem here is in line:
formset = FooFormSet(prefix='foo_prefix')
When you instantiate FooFormSet() the queryset used to generate the forms is (by default):
FooModel.objects.all()
So, if you already have some FooModel() in your database they will be listed. In this case you can use:
formset = FooFormSet(prefix='foo_prefix', queryset=FooModel.objects.none())
You can see more information about this in Django's Documentation:
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#changing-the-queryset
I am trying to produce a template with many addresses (forms), where you can add, edit and remove them.
Am I doing something wrong with formsets? Here are my views:
#login_required
def addresses(request):
AddressesFormset = modelformset_factory(Address,
can_delete = True,
extra = 0,
exclude = ['user'])
log.debug('Queryset: %s', request.user.addresses.all())
if request.method == 'POST':
log.debug('Formset from POST')
formset = AddressesFormset(request.POST)
if formset.is_valid():
log.debug('Saving form')
formset.save()
log.debug('Fromset from queryset')
formset = AddressesFormset(queryset = request.user.addresses.all())
else:
log.debug('Form is not valid')
else:
log.debug('Fromset from queryset')
formset = AddressesFormset(queryset = request.user.addresses.all())
return render_to_response('accounts/addresses.html', locals(), context_instance = RequestContext(request))
#login_required
def add_address(request):
address = Address.objects.create(user = request.user)
address.save()
return HttpResponseRedirect('/accounts/addresses/')
And template:
{{ formset.management_form }}
{% for form in formset.forms %}
<table class="accountT">
<tr class="accountTT">
<td><p>Ulica, nr domu, mieszkania:</p></td>
<td>{{ form.street.errors }}{{ form.street }}</td>
</tr>
<tr class="accountTT">
<td><p>Miejscowość:</p></td>
<td>{{ form.city.errors }}{{ form.city }}</td>
</tr>
<tr class="accountTT">
<td><p>Kod pocztowy:</p></td>
<td>{{ form.zipcode.errors }}{{ form.zipcode }}</td>
</tr>
<tr class="accountTT">
<td><p>Telefon kontaktowy:</p></td>
<td>{{ form.phone.errors }}{{ form.phone }}</td>
</tr>
<tr>
<td><p>Usuń:</p></td>
<td>{{ form.DELETE }}</td>
</tr>
{{ form.id }}
</table>
{% endfor %}
Edit:
The problem is that adding a form I have to save the formset (in add_address()). I would like to see how do you treat formsets properly. I don't understand it at all ;).
Thanks in advance,
Etam.
Well, you don't say what your problem is, but you are doing at least one thing wrong.
After confirming that the formset is valid, and then saving it, for some reason you then instantiate another formset and fall straight through to the render_to_response at the end of the function, so you end up displaying a set of blank forms again.
What you should do at that point is redirect somewhere else, eg to a confirmation page.