ManagementForm data missing error while formset validation
I get this error when I try to save a parent form with intermediate m2m table child formset. I don't know how to solve because the lack of information about this error in Traceback. Please help!
models.py
class Material(models.Model):
name = models.CharField(max_length=200)
familiy = models.ForeignKey(Material_family, on_delete=models.CASCADE, null=True)
…
class Purchase(models.Model):
number = models.IntegerField()
date = models.DateField()
…
class Purchase_detail(models.Model):
material = models.ForeignKey(Material, on_delete=models.CASCADE)
purchase = models.ForeignKey(Purchase, on_delete=models.CASCADE)
quantity = models.IntegerField()
unit_value = models.IntegerField(default=0)
forms.py
class PurchaseModelForm(forms.ModelForm):
class Meta:
model = Purchase
fields = (‘number’,’date’ , ’…’)
def __init__(self, *args, **kwargs):
super(PurchaseModelForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.form_id = 'id-purchase-form'
self.helper.form_method = 'post'
class Purchase_detailModelForm(forms.ModelForm):
class Meta:
model = Purchase_detail
fields = ('material','quantity','unit_value')
def __init__(self, *args, **kwargs):
super(Purchase_detailModelForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.form_id = 'id-purchase-form'
self.helper.form_method = 'post'
self.helper.form_class = 'form-inline'
self.helper.field_template = 'bootstrap3/layout/inline_field.html'
DetailFormSet = forms.inlineformset_factory(Purchase, Purchase_detail, form=Purchase_detailModelForm, extra=1)
views.py
def purchase_new(request, purchase_id=None, *args, **kwargs):
template = 'erp/purchase_form.html'
if purchase_id:
inst = Purchase.objects.get(pk=purchase_id)
else:
inst = Purchase()
if request.method == 'POST':
form = PurchaseModelForm(request.POST or None, request.FILES, prefix='purchase', instance=inst)
formset = DetailFormSet(request.POST or None, request.FILES, prefix='detail')
form_valid = form.is_valid()
if form_valid:
purchase = form.save()
formset.save(commit=False)
for f in formset:
f.compra = purchase
f.save()
return redirect('...')
else:
form = PurchaseModelForm(prefix='purchase',instance=inst)
formset = DetailFormSet(prefix='purchase')
context = { 'form': form, 'formset': formset }
return render(request, template, context )
This is the template
<form method='POST' action="">
{% csrf_token %}
<div>
<h5 style="font-weight: bold;">Datos de la Compra</h5>
{% crispy form form.helper %}<hr/>
<h5 style="font-weight: bold;">Detalle de la Compra <a class="btn btn-rounded btn-sm btn-icon btn-default add-new-form"><i class="fa fa-plus text-success"></i></a></h5>
</div>
{{ formset.management_form|crispy }}
{% for x in formset %}
<div class="form-inline">
{{ x|crispy }}
<hr>
</div>
{% endfor %}
<div class="form-inline" id="empty-row">
{{ formset.empty_form|crispy }}
<hr>
</div>
<button class="btn btn-block btn-primary" >Guardar</button>
</form>
And the traceback is :
Traceback:
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
23. return view_func(request, *args, **kwargs)
File "/Users/jlattus/Dev/italuzbi/src/erp/views.py" in purchase_new
415. formset.save(commit=False)
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/forms/models.py" in save
666. return self.save_existing_objects(commit) + self.save_new_objects(commit)
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/forms/models.py" in save_existing_objects
768. if not self.initial_forms:
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/forms/formsets.py" in initial_forms
189. return self.forms[:self.initial_form_count()]
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/utils/functional.py" in get
35. res = instance.dict[self.name] = self.func(instance)
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/forms/formsets.py" in forms
144. for i in range(self.total_form_count())]
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/forms/formsets.py" in total_form_count
116. return min(self.management_form.cleaned_data[TOTAL_FORM_COUNT], self.absolute_max)
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/utils/functional.py" in get
35. res = instance.dict[self.name] = self.func(instance)
File "/Users/jlattus/Dev/italuzbi/lib/python3.5/site-packages/django/forms/formsets.py" in management_form
98. code='missing_management_form',
Exception Type: ValidationError at /compra/new/
Exception Value: ['Los datos de ManagementForm faltan o han sido manipulados
Related
ValueError: invalid literal for int() with base 10: 'slug-1-2'
2nd time i am facing this error again. I am trying to allow users to edit their comments in any blog post but it seems that there is a problem with this line:
comment = get_object_or_404(Comment, id=post_id)
This has worked for other functions (eg when i created a function that can delete comments) but not this one. Any idea how I can resolve this? I got a feeling its sth to do with when I add comments in the url I use slug and <post_id> when I edit comments url. But it worked for my delete function and i did use post_id for that function. Thanks
models.py
class Comment(models.Model):
post = models.ForeignKey(BlogPost, related_name='comments', on_delete=models.CASCADE)
name = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='name', on_delete=models.CASCADE)
body = models.TextField()
class BlogPost(models.Model):
title = models.CharField(max_length=50, null=False, blank=False, unique=True)
body = models.TextField(max_length=5000, null=False, blank=False)
slug = models.SlugField(blank=True, unique=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
views.py
def edit_own_comment(request, post_id):
context = {}
comment = get_object_or_404(Comment, id=post_id)
if request.method == 'POST':
form = UpdateCommentForm(request.POST, instance=comment)
if comment.name == request.user and form.is_valid():
obj = form.save(commit=False)
obj.save()
messages.success(request, 'Your comment has been edited', extra_tags='editedcomment')
return redirect(reverse("HomeFeed:detail", kwargs={'slug': comment.post.slug }))
form = UpdateCommentForm(
initial = {
"body": comment.body,
}
)
context['form'] = form
return render(request, 'HomeFeed/edit_comment.html', context)
class AddCommentView(LoginRequiredMixin, DetailView, FormView):
login_url = 'must_authenticate'
model = BlogPost
form_class = CommentForm
template_name = 'HomeFeed/add_comment.html'
def form_valid(self, form):
comment = form.save(commit=False)
comment.name = self.request.user
comment.post = self.get_object()
comment.save()
return redirect(reverse("HomeFeed:detail", kwargs={'slug': comment.post.slug }))
def delete_any_comment(request, post_id):
if request.method == 'POST':
comment = get_object_or_404(Comment, id=post_id)
if comment.post.author == request.user:
comment.delete()
return redirect(reverse("HomeFeed:detail", kwargs={'slug': comment.post.slug }))
forms.py
class UpdateCommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['body']
def save(self, commit=True):
comment = self.instance
comment.body = self.cleaned_data['body']
if commit:
comment.save()
return comment
urls.py
path('comments/<slug>', AddCommentView.as_view(), name= "add_comment"),
path('editowncomments/<post_id>', edit_own_comment, name= "edit_own_comment"),
path('deleteanycomments/<post_id>', delete_any_comment, name= "deleteanycomments"),
html
<form class="create-form" method="POST" enctype="multipart/form-data">{% csrf_token %}
<div class="form-group">
<label for="id_body">Body</label>
<textarea class="form-control" rows="8" type="text" name="body" id="id_body" required>{{form.initial.body}}</textarea>
</div>
<button class="submit-button btn btn-lg btn-primary btn-block" type="submit">Edit Comment</button>
</form>
TraceBack
Internal Server Error: /HomeFeed/editowncomments/slug
Traceback (most recent call last):
File "lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "HomeFeed/views.py", line 995, in edit_own_comment
comment = get_object_or_404(Comment, id=post_id)
File "lib/python3.8/site-packages/django/shortcuts.py", line 93, in get_object_or_404
return queryset.get(*args, **kwargs)
File "/lib/python3.8/site-packages/django/db/models/query.py", line 399, in get
clone = self.filter(*args, **kwargs)
File "/lib/python3.8/site-packages/django/db/models/query.py", line 892, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "lib/python3.8/site-packages/django/db/models/query.py", line 910, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1290, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1315, in _add_q
child_clause, needed_inner = self.build_filter(
File "/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1251, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/lib/python3.8/site-packages/django/db/models/sql/query.py", line 1116, in build_lookup
lookup = lookup_class(lhs, rhs)
File "/lib/python3.8/site-packages/django/db/models/lookups.py", line 20, in __init__
self.rhs = self.get_prep_lookup()
File "lib/python3.8/site-packages/django/db/models/lookups.py", line 70, in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
File "/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 972, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'slug'
SLDEM's suggestion:
#login_required(login_url=reverse_lazy("must_authenticate"))
def edit_own_comment(request, post_id):
context = {}
comment = get_object_or_404(Comment, id='slug')
if comment.name != request.user:
return HttpResponse('You did not write the comment.')
if request.method == 'POST':
form = UpdateCommentForm(request.POST or None, instance=comment)
if comment.name == request.user and form.is_valid():
obj = form.save(commit=False)
#this prints a success message after it is safe
obj.save()
return redirect(reverse("HomeFeed:detail", kwargs={'slug': comment.post.slug }))
form = UpdateCommentForm(
initial = {
"body": comment.body,
}
)
context['form'] = form
return render(request, 'HomeFeed/edit_comment.html', context)
path('editowncomments/<int:post_id>', edit_own_comment, name= "edit_own_comment"),
html
{% if not blog_post.comments.all %}
<p>No comments yet... Add a comment</p>
{% else %}
Add a comment
<br>
{% for comment in blog_post.comments.all %}
<strong>
{{ comment.name}}
{{ comment.date_added }}
</strong>
{{ comment.body }}
{% if comment.name == request.user and blog_post.author != request.user %}
<form action = "{% url 'HomeFeed:deletecomments' comment.id %}" method = "POST"> {% csrf_token %}
<button class="btn btn-sm btn-danger">Delete</button>
</form>
{% endif %}
{% if blog_post.author == request.user %}
<form action = "{% url 'HomeFeed:deleteanycomments' comment.id %}" method = "POST"> {% csrf_token %}
<button class="btn btn-sm btn-danger">Delete</button>
</form>
{% endif %}
{% if comment.name == request.user %}
<a class="btn btn-sm btn-warning col-lg-4" href="{% url 'HomeFeed:edit_own_comment' comment_id %}">Edit comment</a>
{% endif %}
{% endfor %}
{% endif %}
detail views.py
class DetailBlogPostView(BlogPostMixin,DetailView):
template_name = 'HomeFeed/detail_blog.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
blog_post=self.get_object()
blog_post.save()
context['blog_post'] = blog_post
account = Account.objects.all()
context['account'] = account
#aka if blog post does belong to me
if blog_post.author != self.request.user:
if self.request.user.is_authenticated and \
blog_post.interest_set.filter(user__id=self.request.user.id).exists():
submittedinterest = True
context["interest_pk"]=blog_post.interest_set.first().pk
#if blog post belongs to me
else:
submittedinterest = False
context['submittedinterest'] = submittedinterest
if blog_post.interest_set.exists():
context["interest_pk"]=blog_post.interest_set.first().pk
return context
Well looks like the issue here is with your url, make it like this:
path('edit-own-comments/<int:post_id>', edit_own_comment, name="edit_own_comment"),
(Add the specification that the passed variable is actually an integer) And then use the value of your Comment instance id in your view.
Ok so based on your edits:
Where you have your html to edit the comment:
{% if comment.name == request.user %}
<a class="btn btn-sm btn-warning col-lg-4" href="{% url 'HomeFeed:edit_own_comment' comment.id %}">Edit comment</a> <!-- here change comment_id to comment.id to pass the correct value to the url -->
{% endif %}
In your view where you are getting the comment:
comment = get_object_or_404(Comment, id=post_id) # also rename post_id to something like comment_id here and in the url to make it more readable
And it should work.
I have a page that has two forms. One form appears as a popup after a user clicks the edit button.
I cannot save information from the form that pops up after clicking the edit button. Not sure what I am doing wrong.
This is what I have in views
def payment_view(request):
form = MentorPaymentForm()
if request.method == 'POST':
form = MentorPaymentForm(request.POST, request.FILES, instance=request.user)
if form.is_valid():
user,mentor = form.save(commit=False)
return redirect('teachers:payment_view')
else:
form = MentorPaymentForm(instance=request.user)
return render(request, 'classroom/teachers/app-instructor-billing.html', {'form': form})
my template:
<form id="billing_details", method="post">
{% csrf_token %}
<label class="col-md-2 control-label">Account Number</label>
<div class="form-group form-control-material">
{{ form.account_num }}
</div>
<label for="bankname" class="col-md-2 control-label">Bank Name</label>
<div class="form-group form-control-material" id="bankname">
{{ form.bank_name }}
</div>
<label for="acc_num" class="col-md-2 control-label">Branch Code</label>
<div class="form-group form-control-material">
{{ form.branch_code }}
</div>
<button type="submit" class="btn btn-success paper-shadow relative" data-z="0.5" data-hover-z="1" data-animated data-dismiss="modal">Update Payment Details</button>
</form>
and the edit button
<i class="fa fa-pencil fa-fw"></i> Edit
here is what i have in urls
path('payment_view', teachers.payment_view, name='payment_view'),
UPDATE
as requested in the comments here is the full traceback when I remove commit=False
Traceback:
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
21. return view_func(request, *args, **kwargs)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
21. return view_func(request, *args, **kwargs)
File "C:\Users\User\Desktop\djangoproject\django-multiple-user-types-example-master\django_school\classroom\views\teachers.py" in payment_view
124. user,mentor = form.save(commit=False)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\django\utils\functional.py" in inner
257. return func(self._wrapped, *args)
Exception Type: TypeError at /teachers/payment_view
Exception Value: 'User' object is not iterable
and forms
class TeacherSignUpForm(UserCreationForm):
email = forms.EmailField(max_length=100)
first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
linkedin = forms.URLField(max_length=200)
address = forms.CharField(max_length=500)
billing_name = forms.CharField(max_length=200)
account_num = forms.IntegerField()
bank_name = forms.CharField(max_length=50)
branch_code = forms.IntegerField()
class Meta(UserCreationForm.Meta):
model = User
fields = ('email', 'username', 'first_name', 'last_name')
def save(self, commit=True):
self.instance.is_teacher = True
user = super(UserCreationForm, self).save(commit=False)
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.save()
mentor = Mentor.objects.get_or_create(
user=user,
linkedin=self.cleaned_data['linkedin'],
address=self.cleaned_data['address'],
billing_name=self.cleaned_data['billing_name'],
account_num=self.cleaned_data['account_num'],
bank_name=self.cleaned_data['bank_name'],
branch_code=self.cleaned_data['branch_code'],
)
return user
...
class MentorPaymentForm(forms.ModelForm):
class Meta:
model = Mentor
fields = ('address', 'billing_name', 'account_num', 'bank_name', 'branch_code')
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.is_teacher = True
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
mentor = Mentor.objects.get_or_create(
user=user,
linkedin=self.cleaned_data['linkedin'],
address=self.cleaned_data['address'],
billing_name=self.cleaned_data['billing_name'],
account_num=self.cleaned_data['account_num'],
bank_name=self.cleaned_data['bank_name'],
branch_code=self.cleaned_data['branch_code'],
)
if commit:
user.save()
return user
user,mentor = form.save(commit=False) can be just form.save()
I have a page with 4 forms, although technically I use it as 1 unique form (basic html), and then in "def post" I handle the request.POST.dict(), I set up a manual validation, according to the foreign keys, and I keep it where it belongs, but it's a simple form, not a modelform or django forms.
On the other hand, I recommend you to switch to CBV, it makes things easier for you, really FBV is tedious.
I want to learn python and web-dev and I am trying to make a functional web application. Right now I have problem with django-autocomplete-light.
I am trying to use autocomplete for my django application. I followed the tutorial, but when I try to search It says that The results could not be loaded.
But results are shown in dropdown list.
I have a form where user can add new invoce, I am trying to use django-autocomplete-light for autocompleting all suppliers so user, doesn't need to search for it.
My models:
class Supplier(models.Model):
supp_name = models.CharField(max_length=255)
mat_number = models.CharField(max_length=255)
organ = models.CharField(max_length=255, null=True, blank=True)
street = models.CharField(max_length=255, null=True, blank=True)
email = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
return self.supp_name.encode("utf-8")
def get_absolute_url(self):
return reverse('supplier-detail', args=[str(self.id)])
def __unicode__(self):
return '%s' % (self.supp_name,)
class Invoice(models.Model):
organization = models.ForeignKey(Group, help_text="organization")
input_peo = models.CharField(max_length=150)
date = models.DateTimeField(auto_now_add=True)
supplier = models.ForeignKey(Supplier, on_delete=models.SET_NULL, null=True, related_name='name')
invoice_number = models.CharField(max_length=100, null=True, blank=True, help_text='Številka preračuna')
price = models.FloatField(null=True, blank=True, help_text='Cena brez DDV')
sum_me = models.IntegerField(null=True, blank=True, help_text='Kolicina')
def __str__(self):
return self.organization.name.encode("utf-8")
def get_absolute_url(self):
return reverse('invoice-detail', args=[str(self.id)])
My views:
class AddInvoice(LoginRequiredMixin, generic.View):
login_url = '/accounts/login/'
redirect_field_name = 'redirect_to'
form_class = InvoiceCreate
template_name = 'invoce/invoce_form.html'
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
invoice = form.save(commit=False)
invoice.organization = request.user.groups.first()
invoice.input_peo = self.request.user.get_full_name()
invoice.supplier = form.cleaned_data['supplier']
invoice.invoice_number = form.cleaned_data['invoice_number']
invoice.price = form.cleaned_data['price']
invoice.sum_me = form.cleaned_data['sum_me']
invoice.save()
return HttpResponseRedirect('/')
return render(request, self.template_name, {'form': form})
'''
*
AUTOCOMPLETE
*
'''
class SupplierAutoComplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = Supplier.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
urls:
urlpatterns += [
url(
r'^autocomplete/$',
views.SupplierAutoComplete.as_view(model=Supplier),
name='supplier-autocomplete',
),
]
If I search just for autocomplete (/autocomplete/) in browser this is what i get:
my forms.py:
class InvoiceCreate(forms.ModelForm):
class Meta:
model = Invoice
fields = [
'supplier',
'invoice_number',
'price',
'sum_me',
]
widgets = {
'supplier': autocomplete.ModelSelect2(url='supplier-autocomplete')
}
and finally my template for form:
{% extends "base_generic.html" %}
{% block content %}
<div class="jumbotron">
<div class="row" style="margin-top:60px">
<form action="" method="post">
{% csrf_token %}
<!-- Left Inputs -->
<div class="col-xs-6 wow animated slideInLeft" data-wow-delay=".5s">
<!-- Supplier -->
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.supplier.errors }}
<label>Supplier:</label>
<div class="container">
{{ form.supplier }}
</div>
</div>
<!-- invoice_number -->
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.invoice_number.errors }}
<input type="text" name="invoice_number" id="id_invoice_number" placeholder="Invoice Number" class="form"/>
</div>
<!-- price -->
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.price.errors }}
<input type="text" name="price" id="id_price" placeholder="Price" class="form"/>
</div>
<!-- sum_me -->
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.sum_me.errors }}
<input type="number" name="sum_me" id="id_sum_me" placeholder="Sum" class="form"/>
</div>
</div><!-- End Left Inputs -->
<!-- Bottom Submit -->
<div class="relative fullwidth col-xs-12">
<!-- Send Button -->
<button type="submit" class="form-btn semibold">Add</button>
</div><!-- End Bottom Submit -->
<!-- Clear -->
<div class="clear"></div>
</form>
</div>
</div>
{{ form.media }}
{% endblock %}
This is traceback I get when I try to search:
[19/Aug/2017 14:29:54] "GET /invoice/autocomplete/?q=frnej HTTP/1.1" 500 16154
[2017-08-19 14:29:54,630] - Broken pipe from ('127.0.0.1', 55490)
Internal Server Error: /invoice/autocomplete/
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/dal/views.py", line 48, in dispatch
return super(ViewMixin, self).dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/django/views/generic/list.py", line 160, in get
self.object_list = self.get_queryset()
File "/Users/miha/Desktop/#application/django/einvoice/invoice/views.py", line 255, in get_queryset
qs = qs.filter(name__istartswith=self.q)
File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 784, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 802, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/usr/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1261, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/usr/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1287, in _add_q
allow_joins=allow_joins, split_subq=split_subq,
File "/usr/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1212, in build_filter
raise FieldError('Related Field got invalid lookup: {}'.format(lookups[0]))
FieldError: Related Field got invalid lookup: istartswith
I'm getting the error message above when trying to load my edit_transaction view. I know what the error means but don't understand why it is happening as it was working before and still works on another similar page. Can provide more code if needed, I'm wondering though if there is something blindingly obvious here, so much so that I can't see it.
Full traceback:
Traceback:
File "/Users/c/.virtualenvs/django-budget/lib/python3.5/site->packages/django/core/handlers/exception.py" in inner
42. response = get_response(request)
File "/Users/c/.virtualenvs/django-budget/lib/python3.5/site->packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/Users/c/.virtualenvs/django-budget/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/c/.virtualenvs/django-budget/lib/python3.5/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
23. return view_func(request, *args, **kwargs)
File "/Users/c/sites/budget/budget/views.py" in edit_transaction
83. form = TransactionForm(instance=transaction)
Exception Type: TypeError at /budget/transaction/3/edit/
Exception Value: init() missing 1 required positional argument: 'request'
extract from urls.py:
url(r'^transaction/(?P<pk>[0-9]+)/edit/$', views.edit_transaction, name='edit_transaction'),
extract from views.py:
#login_required
def edit_transaction(request, pk):
transaction = get_object_or_404(Transaction, pk=pk)
if request.method == "POST":
form = TransactionForm(request.POST, instance=transaction)
if form.is_valid():
transaction = form.save(commit=False)
transaction.updated = timezone.now()
transaction.save()
return redirect('view_transaction_detail', pk=transaction.pk)
else:
form = TransactionForm(instance=transaction)
return render(request, 'budget/new_transaction.html', {'form': form})
template extract:
{% extends 'budget/base.html' %}
{% block content %}
<h2>{{ transaction.title }}</h2>
<h4>{{ transaction.date }}</h4>
<h4>Transaction type: {{ transaction.transaction_type }}</h4>
<h4>Category: {{ transaction.category }}</h4>
<h4>Budgeted amount: {{ transaction.budgeted_amount }}</h4>
<h4>Actual amount: {{ transaction.actual_amount }}</h4>
<h4>Difference: {{ difference }}</h4>
<h4>Comments: {{ transaction.comments }}</h4>
<a class="btn btn-default" href="{% url 'edit_transaction' pk=transaction.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
<a class="btn btn-default" href="{% url 'delete_transaction' pk=transaction.pk %}"><span class="glyphicon glyphicon-remove"></span></a>
<h5>Back to summary</h5>
{% endblock %}
Edited to add TranscationForm code
class TransactionForm(forms.ModelForm):
class Meta:
model = Transaction
fields = ('title', 'transaction_type', 'category', 'budgeted_amount', 'actual_amount', 'date', 'comments',)
#new_category field to allow you to add a new category
new_category = forms.CharField(max_length=30, required=False, label="New Category Title")
def __init__(self, request, *args, **kwargs):
super(TransactionForm, self).__init__(*args, **kwargs)
#category is now not a required field because you will use category OR new_category
self.fields['category'].required=False
#set to allow use of self.request.user to set user for category
self.request = request
def clean(self):
category = self.cleaned_data.get('category')
new_category = self.cleaned_data.get('new_category')
if not category and not new_category:
# raise an error if neither a category is selected nor a new category is entered
raise forms.ValidationError('Category or New category field is required')
elif not category:
# create category from new_category
category, created = Category.objects.get_or_create(title=new_category, defaults={'user': self.request.user})
self.cleaned_data['category'] = category
return super(TransactionForm, self).clean()
it seems like you should write:
form = TransactionForm(request=request, instance=transaction)
instead of :
form = TransactionForm(request.POST, instance=transaction)
I got an error of "global name region is not defined" in the line of "queryset=Result.objects.filter(region=region)".
The mistake might because I shouldn't validate if the queryset result has corresponding record in Database in "def clean".
So I tried to remove "def clean" and put this validation in def get_queryset (the 2nd views.py). Then if I enter something with no queryset result in dababase, it doesn't report error on the form page.
Could any help to find how could I change the code? Thanks in advance.
views.py
class ResultView(ListView):
context_object_name = 'result_list'
template_name = 'result_list.html'
model = Result
def clean(self):
cleaned_data = super(MyForm, self).clean()
region = form.cleaned_data['region']
country= form.cleaned_data['country']
if not Result.objects.filter(region=region,country=country).exists():
self.add_error(ValidationError('No corresponding data exists'))
return cleaned_data
def get_queryset(self):
form = InputForm(self.request.GET)
queryset=Result.objects.filter(region=region) -//here wrong
return queryset
return Result.objects.all()
def get_context_data(self,**kwargs):
context["sales"] = self.get_queryset().aggregate(Sum('sales'))
views.py - if removing def clean-- the error function doesn't work
class ResultView(ListView):
context_object_name = 'result_list'
template_name = 'result_list.html'
model = Result
def get_queryset(self):
form = InputForm(self.request.GET)
if form.is_valid():
country = form.cleaned_data['country']
region = form.cleaned_data['region']
if country !="" and region !="":
if Result.objects.filter(region=region,country=country).exists():
try:
queryset=Result.objects.filter(region=region,country=country)
except:
self.add_error(ValidationError('No corresponding data exists'))
return queryset
return Result.objects.all()
def get_context_data(self,**kwargs):
context["sales"] = self.get_queryset().aggregate(Sum('sales'))
HTML Snippets
<form method="post">{% csrf_token %}
{% csrf_token %}
{{ formset.management_form }}
{{ formset.errors }}
{{ formset.non_field_errors }}
{{ formset.non_form_errors }}
{{ form.non_field_errors }}
......
<!--region--> --it allows to select none
<div class="field {% if field.errors %} field_error{% endif %}" >
<label> Select Region:
{{ form.region }}
{% for region in form.region.choices %}
<option value="region" name= "region" id="id_region">{{region}} </option>
{% endfor %}
</label>
</div>
I don't add " {{ form.non_field_errors }} " because some of the fields it allows to be blank
traceback
Traceback:
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\core\handlers\base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\views\generic\base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\views\generic\base.py" in dispatch
89. return handler(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\views\generic\list.py" in get
159. self.object_list = self.get_queryset()
File "C:\Users\user\Desktop\XXX\result\views.py" in get_queryset
61. Result.objects.filter(region=region,country=country).exists()
this is obvious:
form = InputForm(self.request.GET)
queryset=Result.objects.filter(region=region)
in this scope, the region is not defined, of course.
you need to retrieve the region from the form, sanitize it and then do the query with it
form = InputForm(self.request.GET)
if form.is_valid():
queryset=Result.objects.filter(region=form.cleaned_data['region'])
and further down, it should be:
def get_queryset(self):
form = InputForm(self.request.GET)
if form.is_valid():
country = form.cleaned_data['country']
region = form.cleaned_data['region']
if country !="" and region !="": # <--- moved one intend to right
if Result.objects.filter(region=region,country=country).exists():
try:
queryset=Result.objects.filter(region=region,country=country)
except:
self.add_error(ValidationError('No corresponding data exists'))
return queryset
return Result.objects.all()