I am trying to replicate
if form.is_valid():
With the django form wizard. (this question shouldn't have anything to do with the wizard)
I have this code:
class ContactWizard(SessionWizardView):
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
def done(self, form_list, **kwargs):
if self.request.method == 'POST':
print(form_list)
process_form_data(form_list)
return HttpResponseRedirect('../home')
def process_form_data(form_list):
if form.is_valid():
form_data = [form.cleaned_data for form in form_list]
first_name = form_data[0]['first_name']
last_name = form_data[0]['last_name']
email = form_data[0]['email']
fav_food = form_data[0]['fav_food']
fav_drink = form_data[0]['fav_drink']
user = User.objects.create_user(email)
user.first_name = first_name
user.last_name = last_name
user.email = email
user.save()
user_addon = UserAddon.objects.create(user=user,fav_food=fav_food,fav_drink=fav_drink)
user_addon.save()
return form_data
If i print out form_list i get this
odict_values([<UserAddonForm bound=True, valid=True, fields=(fav_food;fav_drink;first_name,last_name;email)>,ContactForm3 bound=True, valid=True, fields=(info1;info2;message)>])
and if i try running it with just
form.is_valid()
i get
Exception Value: name 'form' is not defined
how can i get an equivalent of the form.is_valid() working?
Thanks
You're passing a form_list to the function process_form_data, but checking against name form (by form.is_valid()) which does not exist at that point.
Assuming form_list is an iterable, you can iterate over it and deal with the forms sequentially:
def process_form_data(form_list):
for form in form_list:
if form.is_valid():
form_data = form.cleaned_data
first_name = form_data[0]['first_name']
last_name = form_data[0]['last_name']
Related
I'm new in django,I just have the error, AttributeError at /registro/ 'NoneType' object has no attribute 'groups', but my form is saving all the data
views.py
def register(request):
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
ui = User()
ui.username = request.POST.get('username')
ui.password = request.POST.get('password')
ui.first_name = request.POST.get('first_name')
ui.last_name = request.POST.get('last_name')
ui.email = request.POST.get('email')
# user = User.objects.create_user(username=username,first_name=first_name,last_name=last_name,email=email,password=password)
user = ui.save()
obj = User.objects.latest('id')
cli = Client_profile_master()
cli.first_name = request.POST.get('first_name')
cli.last_name = request.POST.get('last_name')
cli.email = request.POST.get('email')
cli.mobile_no = request.POST.get('mobile')
cli.address_1 = request.POST.get('address1')
cli.address_2 = request.POST.get('address2')
cli.image=request.FILES.get('image')
cli.user=obj
# emp.save()
# client = Client_profile_master.objects.create(first_name=first_name,last_name=last_name,email=email,mobile=mobile,address1=address1,address2=address2,image=image,user=obj)
cli.save()
username = form.cleaned_data.get('username')
group = Group.objects.get(name='Client')
user.groups.add(group)
messages.success(
request, f'Account created successfully for {username} !!!')
return redirect('login')
else:
return redirect('/')
else:
form = CreateUserForm()
return render(request, 'sites/register.html', {'form': form})
The error is occuring for this line: user = ui.save(), Model's save method does not return anything(or returns None), hence value of user is None. Easy fix would be to use ui.groups.add(group).
But you can improve your implementation a lot by using the forms, which you are already using as well as by adding a new one. For example:
# form
class CliForm(forms.ModelForm):
class Meta:
model = ClientProfileMaster # Using camelcase when declairing class name
exclude = ["user",]
# view
form = CreateUserForm(request.POST)
cli_form = CliForm(request.POST, request.FILES)
if form.is_valid() and cli_form.is_valid():
user = form.save()
cli = cli_form.save(commit=False)
cli.user = user
cli.save()
For more information, please the django modelform's documentation.
I have this form:
class addMeal(forms.Form):
name = forms.CharField(
max_length=40,
widget=forms.TextInput(attrs={'class':'form-control','placeholder':'نام وعده'})
)
foods = forms.ModelMultipleChoiceField(
queryset=Food.objects.none(),
widget=forms.SelectMultiple(attrs={'class':'form-control'})
)
def save(self,request):
data = self.cleaned_data
meal = Meals(name=data['name'],user=request.user,foods=data['foods'])
meal.save()
def __init__(self, user=None,*args, **kwargs, ):
super().__init__(*args, **kwargs)
if user is not None:
self.fields['foods'].queryset = Food.objects.filter(user=user)
class Meta:
model = Meals
and this view:
#login_required
def addmeal(request):
if request.method == 'POST':
form = addMeal(request.POST)
if form.is_valid():
form.save(request)
return redirect('food:index')
else:
form = addMeal(user=request.user)
return render(request,'addmeal.html',{'form':form})
when i fill out form and press submit django give me error(Field 'id' expected a number but got <QueryDict: {'csrfmiddlewaretoken': ['C2B8y3kLCa5IQ0S5Mvk7Tw0NTU4pNlYicppWlsIL1LCrcc8AuCQzjJkqWNUot4z6'], 'name': ['شام'], 'foods': ['1']}>.).
what should i do to fix it?
Since user is the first parameter, you pass the data as second, so:
#login_required
def addmeal(request):
if request.method == 'POST':
form = addMeal(user=request.user, data=request.POST)
if form.is_valid():
form.save(request)
return redirect('food:index')
else:
form = addMeal(user=request.user)
return render(request,'addmeal.html',{'form':form})
I have a form in my application which has a hidden form field, the value of which I want to set in my corresponding view after submitting the form.
forms.py
class EvangelizedForm(forms.ModelForm):
first_name = forms.CharField(help_text="First Name")
last_name = forms.CharField(help_text="Last Name")
email = forms.CharField(help_text="Email ID")
mobile_no = forms.CharField(help_text="Mobile number")
twitter_url = forms.CharField(help_text="Twitter URL")
twitter_followers = forms.CharField(widget = forms.HiddenInput()) #Hidden form field
class Meta:
model = Evangelized
fields = ('first_name','last_name', 'twitter_url', 'email', 'mobile_no')
models.py
class Evangelized(models.Model):
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.EmailField()
mobile_no = models.CharField(unique=True, max_length = 10, validators=[RegexValidator(regex='^\w{10}$', message='Mobile number should be strictly of 10 digits.')])
twitter_url = models.CharField(unique=True, max_length=128)
twitter_followers = models.CharField(max_length = 128)
views.py
def fillform(request):
follower_count = '250'
if request.method == 'POST':
form = EvangelizedForm(request.POST)
if form.is_valid():
form.fields['twitter_followers'] = follower_count
form.save(commit=True)
return index(request)
else:
form.errors
else:
#form = EvangelizedForm()
if request.user.is_authenticated():
form = EvangelizedForm(initial={'first_name': request.user.first_name,
'twitter_url': 'https://twitter.com/' + request.user.username,
'last_name': request.user.last_name})
else:
form = EvangelizedForm()
context = RequestContext(request,
{'request': request,
'user': request.user, 'form':form})
#return render(request, 'rango/fillform.html', {'form': form, 'context_instance':context})
return render_to_response('rango/fillform.html',
context_instance=context)
Basically, I'm trying to set the value of twitter_followers (which is a hidden form field in forms.py) in my index view, by:
follower_count = '250'
..
..
form.fields['twitter_followers'] = follower_count
By doing this, I'm expecting the value of 'twitter_followers' in the database after submitting the form to be '250'. However, this approach doesn't seem to be working.
What's the right way to set values to certain attributes in the database manually using views?
You need to set it on the model instance, which is the result of form.save. That's the main reason for the commit argument in the first place.
if form.is_valid()
obj = form.save(commit=True)
obj.twitter_follower = follower_count
obj.save()
You can override the save method of the form, with something like this:
def save(self, *args, **kwargs)
twitter_followers = kwargs.pop('twitter_followers', 0)
self.instance.twitter_followers = twitter_followers
super(Evangelized, self).save(args, kwargs)
And then in the view just have to call in this way:
form.save(twitter_followers=250)
I have a from created which is generated by a model. I can save the form, but the form data is not inserted into the table. The insert occurs, but with blank data. Any help would be greatly appreciated.
models.py
class HelpDefinition(models.Model):
org = models.IntegerField(default=0)
help_type = models.CharField(max_length=255)
help_content = models.TextField(blank=True)
def __unicode__(self):
return self.name
views.py
def index(request, org_id=None):
help_def = HelpDefinition()
if org_id:
help_def = HelpDefinition.objects.get(org=org_id)
if request.method == 'POST':
form = FormHelp(request.POST)
if form.is_valid():
help_def.save()
messages.success(request, 'Saved!')
else:
messages.error(request, 'Ugh')
else:
form = FormHelp(request=request, initial=initial_data)
return {
'form': form,
}
forms.py
class FormHelp(forms.Form):
org = forms.CharField(widget=forms.HiddenInput, required=True)
help_type = forms.ChoiceField(abel='Text', required=True)
help_content = forms.CharField(label='Description', required=True, widget=forms.Textarea)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(FormHelp, self).__init__(*args, **kwargs)
Due that you dont use ModelForm, you need to set your attributes one by one.
if request.method == 'POST':
form = FormHelp(request.POST)
if form.is_valid():
help_def.org = form.cleaned_data.get("org")
help_def.help_type = form.cleaned_data.get("help_type")
help_def.help_type = form.cleaned_data.get("help_content")
help_def.save()
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)