How to get the ChoiceField value from a form in Django? - python

I want to get the chosen email-id from a drop down list made from ChoiceField. I have written a code but apparently it is not working.
How do I do it ?
Here is my views.py
#login_required
def assign(request):
if request.method == 'POST':
assign_now = AssignTask(data=request.POST, user=request.user)
if assign_now.is_valid():
task_title = assign_now.cleaned_data.get('title')
task_description = assign_now.cleaned_data.get('desc')
assign_email = assign_now.cleaned_data('assign_to')
assign_email = dict(AssignTask.fields['assign_to'].choices)[assign_email]
user_details = User.objects.get(email=assign_email)
t = Task(title=task_title, description=task_description, assigned_to=user_details)
t.save()
return HttpResponse('<h2>Successfully assigned task</h2>')
else:
return HttpResponse('<h2><Task assignment failed/h2>')
else:
return HttpResponse('<h2>Request method error</h2>')
Here is my forms.py
class AssignTask(forms.Form):
title = forms.CharField(max_length=200)
description = forms.CharField(widget=forms.Textarea)
assign_to = forms.ChoiceField(widget=forms.Select(choices=[]))
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
user_email = self.user.email.split('#')[1]
super(AssignTask, self).__init__(*args, **kwargs)
self.fields['assign_to'] = forms.ChoiceField(choices=[(i.email, i.email) for i in User.objects.filter(is_active=True, email__icontains=user_email)])
Error that I am getting is:
File "/home/gblp250/PycharmProjects/assignment/todoapp/views.py" in assign
118. assign_email = assign_now.cleaned_data('assign_to')
Exception Type: TypeError at /assign
Exception Value: 'dict' object is not callable

From the error traceback, We can understand, you are missing a .get() function
so, try this,
assign_email = assign_now.cleaned_data.get('assign_to')
instead of
assign_email = assign_now.cleaned_data('assign_to')
complete view function
#login_required
def assign(request):
if request.method == 'POST':
assign_now = AssignTask(data=request.POST, user=request.user)
if assign_now.is_valid():
task_title = assign_now.cleaned_data.get('title')
task_description = assign_now.cleaned_data.get('desc','Sample Description')
assign_email = assign_now.cleaned_data.get('assign_to')
user_details = User.objects.get(email=assign_email)
t = Task(title=task_title, description=task_description, assigned_to=user_details)
t.save()
return HttpResponse('<h2>Successfully assigned task</h2>')
else:
return HttpResponse('<h2><Task assignment failed/h2>')
else:
return HttpResponse('<h2>Request method error</h2>')

Related

Django form with dynamic queryset ModelMultipleChoiceField

I'm trying to pass a queryset to a forms ModelMultipleChoiceField as an initial value. I want to send a filtered queryset as all the choices and an initial selection. It seems to fail is_valid. Can anyone tell me what I'm doing wrong?
forms.py
class sendListForm(forms.Form):
recipients = forms.ModelMultipleChoiceField(queryset = CustomUser.objects.all())
title = forms.CharField(max_length=100,required=True)
description = forms.CharField(max_length=500,required=False,widget=forms.Textarea(attrs={'cols': 20, 'rows': 4}))
extraInfo = forms.CharField(max_length=500,required=False, help_text='Add a message to send',widget=forms.Textarea(attrs={"rows":4, "cols":20}),label='Extra Message')
startDate = forms.DateField(required=False,widget=forms.HiddenInput())
startTime = forms.TimeField(required=False,widget=forms.HiddenInput())
endDate = forms.DateField(required=False,widget=forms.HiddenInput())
endTime = forms.TimeField(required=False,widget=forms.HiddenInput())
yearName = forms.CharField(widget=forms.HiddenInput())
def __init__(self, *args, **kwargs):
recipients = kwargs.pop('recipients')
super(sendListForm, self).__init__(*args, **kwargs)
self.fields['recipients'] = forms.ModelMultipleChoiceField(queryset=recipients)
views.py
def eventSendList(request, modelPk=None):
event = get_object_or_404(Event, pk=modelPk)
if request.method == 'POST':
form = sendListForm(request.POST,recipients=CustomUser.objects.all())
if form.is_valid():
print('valid')
baseInfo = {
'recipients':recipients,
'title':event.title,
'description':event.description,
'startDate':event.startDate,
'startTime':event.startTime,
'endDate':event.endDate,
'endTime':event.endTime,
'yearName':event.yearName.name,
}
classParents = CustomUser.objects.all()
form = sendListForm(initial=baseInfo,recipients=classParents)
return render(request, 'page/sendListForm.html',{'form':form})
It never gets past the if form.is_valid():... in the view.
you can easily find your form errors by printing the form.errors field.

Unable to Update InlineFormset in Django with CBV

class PreChildrenView(CreateView):
model = PreDealDetails2
template_name = 'cam_app/children_form.html'
fields = '__all__'
success_url = reverse_lazy('forms_app:deal-entering')
session_initial = 'children_'
def get_initial(self,**kwargs):
initial = super(PreChildrenView, self).get_initial(**kwargs)
initial['deal_id'] = self.request.session['deal_id']
return initial
def get_context_data(self, **kwargs):
data = super(PreChildrenView, self).get_context_data(**kwargs)
if self.request.POST:
data['childrens'] = ChildrenFormSet(self.request.POST)
print('post')
else:
print('get')
data['childrens'] = ChildrenFormSet()
data['childrens'].extra = 5
data['info'] = 'Children Details'
return data
def form_valid(self, form):
print('wwwww')
context = self.get_context_data()
childrens = context['childrens']
if form.is_valid():
pass
if childrens.is_valid():
count = 0
self.object = form.save()
childrens.instance = self.object
childrens.save()
self.request.session[self.session_initial + 'children_count'] = count
self.request.session['valid_children'] = True
messages.success(self.request, 'Successfully filled Children Details')
return self.render_to_response(self.get_context_data(form=form))
else:
return super(PreChildrenView, self).form_invalid(form)
class UpdatePreChildrenView(UpdateView):
model = PreDealDetails2
template_name = 'cam_app/children_form.html'
fields = '__all__'
success_url = reverse_lazy('forms_app:deal-entering')
session_initial = 'children_'
def get_object(self, queryset=None):
return PreDealDetails2(deal_id = self.request.session['deal_id'])
def get_context_data(self, **kwargs):
data = super(UpdatePreChildrenView, self).get_context_data(**kwargs)
if self.request.POST:
a = PreDealDetails2.objects.get(deal_id = self.request.session['deal_id'])
data['childrens'] = ChildrenFormSet(self.request.POST)
print('post')
else:
print('get')
data['childrens'] = ChildrenFormSet(instance=self.object)
data['childrens'].extra = 5
data['info'] = 'Children Details'
return data
def form_valid(self, form):
print('update valid')
context = self.get_context_data()
childrens = context['childrens']
if form.is_valid():
print('wejri')
self.object =form.save()
if childrens.is_valid():
childrens.instance = self.object
childrens.save()
count = 0
self.request.session[self.session_initial + 'children_count'] = count
self.request.session['valid_children'] = True
messages.success(self.request, 'Successfully filled Children Details')
return self.render_to_response(self.get_context_data(form=form))
else:
return super(UpdatePreChildrenView, self).form_invalid(form)
else:
print('sfeief')
class PreChildrenRedirectView(RedirectView):
def get_redirect_url(self):
flag = 0
try:
PreDealDetails2.objects.get(deal_id=self.request.session['deal_id'])
flag = 1
except:
pass
if flag == 1:
return reverse("cam_app:update-prechildren-view")
else:
return reverse("cam_app:create-prechildren-view")
I am using above code to enter details to form and later update form.
CreateView is working fine and saving data.
UpdateView is displaying data. When i try to save updateview it is showing following error :-
Code Flow :-
First PreChildrenRedirectView is called. It checks if data already exist or not. If it does then Updateview is called and if it doesnot exist then Createview is called.
I am not using slug. Instead i am using get_object in Updateview. Let me know what is causing problem or how to solve the error.
Update
I have changed the forms.py to remove the error in child. But Deal Id is still showing error. I am also attaching the forms.py below
class ChildrenForm(forms.ModelForm):
class Meta:
model = PreChildrenDetails
fields = '__all__'
def __init__(self, *args, **kwargs):
super(ChildrenForm, self).__init__(*args, **kwargs)
self.fields['deal_id'].widget.attrs['readonly'] = True
self.helper = FormHelper(self)
self.helper.form_show_labels = False
def clean(self):
print('wow')
pass
ChildrenFormSet = inlineformset_factory(PreDealDetails2,PreChildrenDetails, form=ChildrenForm, fields = '__all__', extra=1)
Below is screenshot of error after updating

__init__() got multiple values for argument 'crescator'

I have a ModelForm and in a ModelChoiceField I need to filter objects by request.user. When data is submitted, I got the error "init() got multiple values for argument 'crescator' ". How can I repair that?
#My Form
class AdaugaPereche(forms.ModelForm):
boxa = forms.IntegerField(label="Boxa", min_value=1)
sezon = forms.CharField(label="Sezon reproducere", initial=datetime.now().year)
mascul = forms.ModelChoiceField(queryset=None, label="Mascul", empty_label="Alege mascul")
femela = forms.ModelChoiceField(queryset=None, label="Femela", empty_label="Alege femela")
serie_pui_1 = forms.TextInput()
serie_pui_2 = forms.TextInput()
culoare_pui_1 = forms.ModelChoiceField(queryset=None, label="Culoare pui 1", empty_label="Alege culoarea",
required=False)
culoare_pui_2 = forms.ModelChoiceField(queryset=None, label="Culoare pui 2", empty_label="Alege culoarea",
required=False)
data_imperechere = forms.DateInput()
primul_ou = forms.DateInput()
data_ecloziune = forms.DateInput()
data_inelare = forms.DateInput()
comentarii = forms.TextInput()
# Functie pentru filtrarea rezultatelor dupa crescator
def __init__(self, crescator, *args, **kwargs):
super(AdaugaPereche, self).__init__(*args, **kwargs)
self.fields['mascul'].queryset = Porumbei.objects.filter(crescator=crescator, sex="Mascul",
perechi_masculi__isnull=True)
self.fields['femela'].queryset = Porumbei.objects.filter(crescator=crescator, sex="Femelă",
perechi_femele__isnull=True)
self.fields['culoare_pui_1'].queryset = CuloriPorumbei.objects.filter(crescator=crescator)
self.fields['culoare_pui_2'].queryset = CuloriPorumbei.objects.filter(crescator=crescator)
class Meta:
model = Perechi
fields = "__all__"
#My view
def perechenoua(request):
if request.method == "POST":
form = AdaugaPereche(request.POST, crescator=request.user)
if form.is_valid():
obj = form.save(commit=False)
obj.crescator = request.user
obj.save()
return HttpResponseRedirect("/perechi/")
else:
form = AdaugaPereche(crescator=request.user)
context = {
'form': form
}
template = loader.get_template("adauga-pereche.html")
return HttpResponse(template.render(context, request))
May the problem be obj = form.save(commit=False) obj.crescator = request.user obj.save() ?
The __init__ function of the form signature takes as first parameter here crescator, but you pass request.POST as that parameter, and furthermore you also pass this as a named parameter. By reordening the parameter, this should work:
class AdaugaPereche(forms.ModelForm):
# ...
def __init__(self, *args, crescator=None, **kwargs):
super(AdaugaPereche, self).__init__(*args, **kwargs)
self.fields['mascul'].queryset = Porumbei.objects.filter(crescator=crescator, sex="Mascul",
perechi_masculi__isnull=True)
self.fields['femela'].queryset = Porumbei.objects.filter(crescator=crescator, sex="Femelă",
perechi_femele__isnull=True)
self.fields['culoare_pui_1'].queryset = CuloriPorumbei.objects.filter(crescator=crescator)
self.fields['culoare_pui_2'].queryset = CuloriPorumbei.objects.filter(crescator=crescator)
# ...

form.is_valid() is false why?

I want to store a POST request to a database, so I a had model form MessageForm and called it from views to validate the data and save it.
models.py
class phoneNumber(models.Model):
address = models.CharField(max_length=15)
def __str__(self):
return self.address
class Message(models.Model):
to = models.ForeignKey(phoneNumber, null=True)
sentfrom = models.CharField(max_length=15, null=True)
content = models.TextField(null=True)
def __str__(self):
return '%s' % (self.content)
forms.py
class MessageForm(forms.ModelForm):
class Meta:
model = Message
fields = '__all__'
def __init__(self, *args, **kwargs):
to = kwargs.pop('to', '')
super(MessageForm, self).__init__(*args, **kwargs)
self.fields['to']=forms.ModelChoiceField(queryset=phoneNumber.objects.filter(address=to))
views.py
#csrf_exempt
def incoming(request):
if request.method == "POST":
form = MessageForm(request.POST)
if form.is_valid():
twiml = '<Response><Message>Yes</Message></Response>'
else:
twiml = '<Response><Message>No</Message></Response>'
else:
twiml = '<Response><Message></Message></Response>'
return HttpResponse(twiml, content_type='text/xml')
Nothing is saved and I get No response when I test it.
You can access your errors in views.py
#csrf_exempt
def incoming(request):
if request.method == "POST":
form = MessageForm(request.POST)
if form.is_valid():
twiml = '<Response><Message>Yes</Message></Response>'
else:
print(form.errors)
print(form.non_field_errors)
twiml = '<Response><Message>No</Message></Response>'
else:
twiml = '<Response><Message></Message></Response>'
return HttpResponse(twiml, content_type='text/xml')
Have you tried:
def __init__(self, *args, **kwargs):
to = kwargs.pop('to', '')
super(MessageForm, self).__init__(*args, **kwargs)
self.fields['to'].queryset = phoneNumber.objects.filter(address=to)
Also I'm not sure if you want to pass anything to the form in views method, because right now your to in form is empty string, so your queryset is querying on phoneNumber.objects.filter(address=''), which may or may not be what you want.
Edit:
The reason that to is empty string because kwargs.pop('to', '') means "pop argument to out from kwargs, if to is not there the default is ''". In your views you do:
form = MessageForm(request.POST)
but you didn't feed the constructor with any to argument, so kwargs.pop('to', '') would get '' as default value. You might need something like:
form = MessageForm(request.POST, to="white house")

Django: CommentForm Not Working Correctly, No Error?

Attempting to create a comment form as follows:
class CommentCreationForm(forms.Form):
body = forms.CharField(widget=forms.Textarea)
author = forms.CharField()
def __init__(self, *args, **kwargs):
super(CommmentCreationForm, self).__init__(*args, **kwargs)
self.user = kwargs.pop('user', None)
def save(self):
data = self.cleaned_data
comment = Comment(body=data['body'], author=data['author'], user=self.user)
comment.save()
def clean(self):
return self.cleaned_data
views.py
#login_required
def create(request):
try:
if is_post(request):
form = CommentCreationForm(request.user)
if form.is_valid():
print 'valid'
form.save()
return render_to_response("login.html", context_instance = RequestContext(request))
return render_to_response("login.html", context_instance = RequestContext(request))
return render_to_response("create.html", {'form':CommentCreationForm()}, context_instance = RequestContext(request))
except Exception as e:
print str(e)
If I submit the form, it returns: 'User' object has no attribute 'get'. I'm sure I'm doing something very wrong, but I don't know what.
First, The form is incorrectly initialized, the signature of Form.__init__ looks like:
Form.__init__(data=None, files=None, ...)
# When you put
form = CommentCreationForm(request.user)
# The data is feed w/ request.user ...
Second, self.user = kwargs.pop('user', None) would always set self.user to None, unless the invoking code is:
form = CommentCreationForm(request.POST, user=request.user)
Finally, a better approach is to refer the request.user directly, in some scope, for example:
def make_commment_form_cls(user):
class CommentCreationForm(forms.Form):
body = forms.CharField(widget=forms.Textarea)
author = forms.CharField()
def save(self):
data = self.cleaned_data
# HERE
comment = Comment(body=data['body'], author=data['author'], user=user)
comment.save()
return CommentCreationForm
In create view
# replace
form = CommentCreationForm(request.user)
# with
form = make_comment_form_cls(request.user)(request.POST)

Categories