Can anyone help me with this. I don't understand this error
IndexError at /customerList/
tuple index out of range
and it came from this code
self.Customer = get_object_or_404(customer, name__iexact=self.args[0])
I want to be able to do ListView some of the fields from two forms that is from customerForm (F_NAME, L_NAME) and buildingForm (B_USE, B_TYPE). Any help is very much is very very much appreciated. Thank u.
Traceback:
File "c:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "c:\Python27\lib\site-packages\django\views\generic\base.py" in view
48. return self.dispatch(request, *args, **kwargs)
File "c:\Python27\lib\site-packages\django\views\generic\base.py" in dispatch
69. return handler(request, *args, **kwargs)
File "c:\Python27\lib\site-packages\django\views\generic\list.py" in get
114. self.object_list = self.get_queryset()
File "f:\iqgit\amon\amonsolution\solution\views.py" in get_queryset
59. self.Customer = get_object_or_404(customer, name__iexact=self.args[0])
Exception Type: IndexError at /customerList/
Exception Value: tuple index out of range
views.py
class customerListView(ListView):
template_name = "customerList.html",
model = customer
context_object_name = "customer_list"
def get_queryset(self):
self.Customer = get_object_or_404(customer, name__iexact=self.args[0])
return building.objects.filter(Customer=self.Customer)
def get_context_data(self, **kwargs):
context = super(customerListView, self).get_context_data(**kwargs)
context['building_list'] = building.objects.all()
return context
forms.py
class customerForm(forms.ModelForm):
F_NAME = forms.CharField(widget=forms.TextInput()
L_NAME = forms.CharField(widget=forms.TextInput()
EMAIL = forms.CharField(widget=forms.TextInput()
ADD = forms.CharField(widget=forms.TextInput()
class Meta:
model = customer
class buildingForm(forms.ModelForm):
CUSTOMER = forms.CharField(widget=forms.TextInput()
B_FLOORSPACE = forms.CharField(widget=forms.TextInput()
B_YEAR = forms.CharField(widget=forms.TextInput()
B_USE = forms.ChoiceField(widget=forms.RadioSelect(), choices=c.Use)
B_TYPE = forms.ChoiceField(widget=forms.RadioSelect(), choices=c.Type)
class Meta:
model = building
exclude = ('CUSTOMER',)
urls.py
url(r'^customerList/',customerListView.as_view(), name= "customerList_view"),
customerList.html
...some of code...
{% for customer in customer_list %}
<tr class = {% cycle "row_even" "row_odd" %}>
<td>{{ customer.id }}</td>
<td class ="name"> {{ customer.F_NAME }} {{ customer.L_NAME }}</td>
<td class ="b_use"> {{ building.B_USE }}{{ building.B_TYPE }}</td>
...some of code...
You are trying to call a positional argument (self.args[0]) passed from the URL conf but you haven't added any positional arguments to your actual url. If you look at how a request is processed, you will notice that:
4 . Once one of the [url] regexes matches, Django imports and calls the given view, which is a simple Python function. The view gets passed an HttpRequest as its first argument and any values captured in the regex as remaining arguments.
You aren't passing any arguments (neither positional or named) to your view so there is nothing in self.args or self.kwargs. You need to change your URL to something like:
url(r'^customerList/(\w+)/',customerListView.as_view(), name= "customerList_view"),
or ideally make use of named arguments such as:
url(r'^customerList/(?P<name>\w+)/',customerListView.as_view(), name= "customerList_view"),
so that you can instead use self.kwargs.get("name", None)
Related
I am still learning Python via Django and have been doing most of my methods in views. I have been told that it is better practice to put them in my models under a Manager. I have the following code grabbing the product info and I believe the id to fill my model. but its throwing an error. Any help would be great.
Updated error after moving stuff in to model. Now it does't regonize request.session
Traceback:
File "C:\Users\dbhol\Desktop\DojoAssignments\Python\myenvirnoments\djangoENv\lib\site-packages\django\core\handlers\exception.py" in inner
42. response = get_response(request)
File "C:\Users\dbhol\Desktop\DojoAssignments\Python\myenvirnoments\djangoENv\lib\site-packages\django\core\handlers\base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "C:\Users\dbhol\Desktop\DojoAssignments\Python\myenvirnoments\djangoENv\lib\site-packages\django\core\handlers\base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\dbhol\Desktop\blackbelttest ver 1\blackbelttest\apps\blackbeltapp\views.py" in create
43. viewsResponse = Myblackbelt.objects.add_product(request.POST)
File "C:\Users\dbhol\Desktop\blackbelttest ver 1\blackbelttest\apps\blackbeltapp\models.py" in add_product
9. secreteid= User.objects.get(id=request.session['loguser_id'])
Exception Type: NameError at /blackbelt/create
Exception Value: global name 'request' is not defined
Html matters
<form class="" action="{% url 'blackbelt:create' %}" method="post">
{% csrf_token %}
<p>Product: <input type="text" name="product" value=""></p>
<input type="submit" name="" value="Create">
</form>
view.py that matters
def create(request):
viewsResponse = Myblackbelt.objects.add_product(request.POST)
return redirect ('blackbelt:index')
Models in full
from __future__ import unicode_literals
from django.db import models
from ..logReg.models import User
class ProductManager(models.Manager):
def add_product(self, postData):
print 'dog here'
secreteid= User.objects.get(id=request.session['loguser_id'])
Myblackbelt = self.create(product = postData['product'], creator=secreteid)
class Myblackbelt(models.Model):
product = models.CharField(max_length = 70)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
loguser = models.ManyToManyField(User, related_name='loguser')
creator = models.ForeignKey(User, related_name='creator')
objects = ProductManager()
Your code is not well structure and it'll break soon. However, to overcome the MultiValueDictKeyError error write these:
# views.py
def create(request):
if request.method == 'POST':
viewsResponse = Myblackbelt.objects.add_product(request.POST)
secreteid= User.objects.get(id=request.session['user_id'])
return redirect ('blackbelt:index')
class ProductManager(models.Manager):
def add_product(self, postData):
# always set a default value if dict key is not found
# of course you must (also) check if postData is of type dict
product = postData.get('product', None)
creator_id = postData.get('loguser_id', None)
if product is not None and creator_id is not None:
creator = User.objects.get(id=creator_id)
Myblackbelt = self.create(product=product, creator=creator)
print 'dog here'
I succesfully implemented the django-selectable AutoCompleteSelectField in a simple form that lets you enter an note description and a corresponding domain category ( domain and foreign key picked from other Many-to-One relationship
See: most relevant code:
# MODEL
class Note(models.Model):
notetext = models.TextField(default='nota')
domain = models.ForeignKey(Domain)
def __str__(self):
return self.notetext
def get_absolute_url(self):
return reverse('note:note_detail', args= [self.id])
# FORM
class NoteForm(forms.ModelForm):
domainselect = AutoCompleteSelectField(lookup_class= DomainLookup, label='Pick a domain category', required=True,)
def __init__(self, *args, **kwargs):
super(NoteForm, self).__init__(*args, **kwargs)
domaintext = self.instance.domain.title
self.fields['domainselect'].widget = AutoCompleteSelectWidget(DomainLookup , { 'value': self.instance.domain.title } )
def save(self, commit=True):
self.instance.domain = self.cleaned_data['domainselect']
return super(NoteForm, self).save(commit=commit)
class Meta:
model = Note
fields = ('notetext',)
widgets = {
'domain' : AutoCompleteSelectWidget(DomainLookup), }
# VIEW
class EditNoteView(generic.edit.UpdateView):
model = Note
form_class = NoteForm
success_url = "/note/"
def get_queryset(self):
base_qs = super(EditNoteView, self).get_queryset()
return base_qs.filter()
def get_object(self):
object = get_object_or_404(Note,id=self.kwargs['id'])
return object
# TEMPLATE
{% extends "base_sidebar.html" %}
{%block content%}
<form action="" method="post">
{{form.as_p}}
<button type="submit">Save</button>
{% csrf_token %}
{% load selectable_tags %}
{{ form.media.css }}
{{ form.media.js }}
</form>
{%endblock%}
Now, when an existing record is selected for editing via generic.edit.UpdateView in a Modelform, I want to populate the AutocompleteSelectField with the corresponding values ( domain description and id ) formerly saved into the database upon loading the form.
By overwriting the init(self, *args, **kwargs) method of the NoteForm, I was able to get almost this far in the sense that the first HTML input field gets populated.
However, the hidden input value gets set to the same value and pushing the save button results in posting a non valid form as if no domain category was selected.
Here's the page source that is sent back to the Browser:
<p><label for="id_domainselect_0">Pick a domain:</label>
<input data-selectable-allow-new="false" data-selectable-type="text" data-selectable-url="/selectable/domain-domainlookup/" id="id_domainselect_0" name="domainselect_0" type="text" value="politics" />
<input data-selectable-type="hidden" id="id_domainselect_1" name="domainselect_1" type="hidden" value="politics" /></p>
I don't know how to change the context (by setting self.fields['domainselect'].widget) in order to get the title into the domainselect_0 input value and the corresponding pk into the hidden domainselect_1 input value. ?
Thanks for helping me out.
After digging down into the django-selectable and Django code it appears the AutocompleteSelectWidget is based on the Django forms.MultiWidget class.
The Django MultiWidget accepts 1 single value (list) that is decomposed into the values corresponding to the respective 'subWidgets' through a mechanism implemented in a decompress method. ( see https://github.com/mlavin/django-selectable/blob/master/selectable/forms/widgets.py class SelectableMultiWidget )
So, all you have to do is assign a list containing title and id to the widget:
def __init__(self, *args, **kwargs):
super(NoteForm, self).__init__(*args, **kwargs)
self.initial['domainselect'] = [self.instance.domain.title , self.instance.domain.id ]
I'm trying to populate in my template a <select> element with data from a form field like this:
forms.py
class CreatePlayerForm(forms.Form):
size = forms.CharField()
views.py
class CreatePlayer(FormView):
...
def get(self, request, *args, **kwargs):
...
boots = Boots.objects.filter(...).values_list('size', flat=True) # return a list
form.initial['boots'] = boots
template
<select id="leftValues4" size="5" multiple>
{% for boot in form.boots %}
<option>{{ boot }}</option>
{% endfor %}
</select>
With the above code I don't get any results.
Any suggestion?
You are not approaching this in the right way at all.
initial is specifically for pre-setting the chosen value. You are trying to populate the list of values. For that, you will need to use an actual field that supports such a list; and that is a ChoiceField, not a CharField.
Secondly, choices need to have an ID value as well as a display value; so you need a list/tuple of 2-tuples.
form:
class CreatePlayerForm(forms.Form):
size = forms.ChoiceField(choices=[])
def __init__(self, *args, **kwargs):
sizes = kwargs.pop('sizes')
super(CreatePlayerForm, self).__init__(*args, **kwargs)
self.fields['sizes'].choices = sizes
view:
class CreatePlayer(FormView):
...
def get_form_kwargs(self, *args, **kwargs):
form_kwargs = super(CreatePlayer, self).get_form_kwargs(*args, **kwargs)
boots = Boots.objects.filter(...).values_list('id', 'size')
form_kwargs['sizes'] = boots
return form_kwargs
template:
{{ form.boots }}
In a blog-ish part of my django app, editing an existing entry results in creating a new entry. It should modify the existing entry.
I have a simple model:
class BlogEntry(models.Model):
...
slug = models.SlugField(unique=True)
and a simple form for editing it:
class BlogEntryForm(forms.ModelForm):
...
slug = forms.CharField(required=False, widget=forms.HiddenInput())
class Meta:
model = BlogEntry
fields = (..., 'slug')
and the view, somewhat simplified, is also straight-forward:
class BlogEditView(View):
#method_decorator(login_required)
def get(self, request, slug=None):
context = {
'user': request.user,
}
if slug is None:
print('Creating new entry.')
context['entry'] = BlogEntryForm()
context['entry'].publication_date = datetime.datetime.now()
return render(request, 'blog/edit.html', context)
print('Using existing entry.')
entry = get_object_or_404(BlogEntry, slug=slug)
context['entry'] = BlogEntryForm(instance=entry)
return render(request, 'blog/edit.html', context)
#method_decorator(login_required)
def post(self, request):
blog_entry_form = BlogEntryForm(request.POST)
if blog_entry_form.is_valid():
blog_entry = blog_entry_form.save(commit=False)
if blog_entry.slug is None or blog_entry.slug == '':
print('New entry, slug is empty.')
blog_entry.creation_date = datetime.datetime.now()
blog_entry.slug = slugify(blog_entry.title) + '_' + hex(random.randint(0, 1e10))
blog_entry.author = request.user
blog_entry.save()
return redirect(reverse('blog/article', args=[blog_entry.slug]))
...
In get(), I confirm with the print's that I am taking the correct branch. If the entry exists, I set entry with the instance. In post(), however, I always take the new entry branch.
The layout has the typical hidden element loop.
{% for hidden in form.hidden_fields %}
{{ hidden }} hidden
{% endfor %}
though, suspiciously, when I look at the served html, I don't see the slug entry, so it's no surprise that it's not getting passed through.
Anyone see what I'm missing?
You should add the slug argument to the post() method as well. This will allow you to get the blog entry to edit from the database and pass this entry to the form as an instance argument:
#method_decorator(login_required)
def post(self, request, slug=None):
blog_entry = BlogEntry.objects.filter(slug=slug).first()
blog_entry_form = BlogEntryForm(request.POST, instance=blog_entry)
...
UPDATE: To pass the slug argument to the post() method you should use the empty action attribute of the <form> tag:
<form action="" method="POST">
In this case the form will be submitted to the url from which it was loaded. So the slug argument for the POST request will be the same as for the GET.
I want to show empty form field if there is nothing to show, otherwise a form field with the value inside:
{% if somevalue %}
{{form.fieldname}} #<---- how do i set the `somevalue` as value of fieldname here?
{% else %}
{{form.fieldname}}
{% endif %}
In your view, if it is a class-based view, do it like so:
class YourView(FormView):
form_class = YourForm
def get_initial(self):
# call super if needed
return {'fieldname': somevalue}
If it is a generic view, or not a FormView, you can use:
form = YourForm(initial={'fieldname': somevalue})
There are multiple ways to provide initial data in django form.
At least some of them are:
1) Provide initial data as field argument.
class CityForm(forms.Form):
location = ModelChoiceField(queryset=City.objects.all(), initial='Munchen')
2) Set it in the init method of the form:
class CityForm(forms.Form):
location = ModelChoiceField(queryset=City.objects.all())
def __init__(self, *args, **kwargs):
super(JobIndexSearchForm, self).__init__(*args, **kwargs)
self.fields['location'].initial = 'Munchen'
3) Pass a dictionary with initial values when instantiating the form:
#views.py
form = CityForm(initial={'location': 'Munchen'})
In your case, I guess something like this will work..
class CityForm(forms.Form):
location = ModelChoiceField(queryset=City.objects.all())
def __init__(self, *args, **kwargs):
super(JobIndexSearchForm, self).__init__(*args, **kwargs)
if City.objects.all().exists():
self.fields['location'].initial = ''
else:
self.field['location'].initial = City.objects.all()[:1]
That all is just for demonstration, you have to adapt it to your case.