I am trying to fill out a form in my Django web application and post it. It is giving me an error
object Application has no attribute cleaned_data
I looked around Stack Overflow at similar questions, but the resolutions for others are not issues with my code. Here is my view:
def single_career(request, a_slug):
a_slug = a_slug.strip('/')
try:
career = Career.objects.get(slug=a_slug)
except:
career = None
if request.method == "POST":
form = Application(request.POST, request.FILES)
Post = True
if form.is_valid():
cleaned_data = Application.cleaned_data
is_valid = True
clean_first = cleaned_data['first_name']
clean_last = cleaned_data['last_name']
clean_email = cleaned_data['email']
clean_phone = cleaned_data['phone']
clean_file = cleaned_data['resume']
clean_message = cleaned_data['message']
date = datetime.datetime.now()
else:
is_valid = False
else:
form = Application()
Post = False
is_valid = False
context = {'career': career, 'form': form, 'post': Post, 'is_valid': is_valid}
template = 'overrides/careers.html'
set_detail_context(request, context)
return render_to_response(template, context, context_instance=RequestContext(request))
the html:
<form action="" method="POST" enctype="multipart/form-data" class="application-form">
{% csrf_token %}
<div class="firstname">
<p>FIRST NAME</p>
{{ form.first_name }}
</div>
<div class="lastname">
<p>LAST NAME</p>
{{ form.last_name }}
</div>
<div class="email">
<p>EMAIL</p>
{{ form.email }}
</div>
<div class="phone">
<p>PHONE</p>
{{ form.phone }}
</div>
{# form fileupload-input is hidden, and extra readonly text-input is there #}
{# to be able to override the styling of the fileupload-input button #}
<div>
<p>ATATCH PDF RESUME</p>
<input class="readonly" type="text" READONLY>
<div class="resume">
{{ form.resume }}
<div>
<a id="browse">BROWSE</a>
</div>
</div>
</div>
<div>
<p>MESSAGE</p>
{{ form.message }}
</div>
<button class="submit-button" type="submit">
APPLY
</button>
</form>
and the form class:
from django import forms
class Application(forms.Form):
first_name = forms.CharField(label="First Name", max_length=50)
last_name = forms.CharField(label="Last Name", max_length=50)
email = forms.EmailField(label="Email", max_length=80)
phone = forms.CharField(label="Phone Number", max_length=30)
resume = forms.FileField(label="Resume", max_length=1000)
message = forms.CharField(label="Message", max_length=800, widget=forms.Textarea)
The validated form is form, not Application.
The cleaned_data belongs to the form instance. You should have:
if form.is_valid():
cleaned_data = form.cleaned_data
You are getting the error because you are trying to fetch it from the form class.
if form.is_valid():
cleaned_data = Application.cleaned_data
Related
I was creating a post based website i want to show the author's name to show up in the post it works in the admin site when adding posts but when i try uploading a post from the site the form is not getting validated therefore it is not getting saved please help
model :
from django.conf import settings
class MemeImg(models.Model):
Title = models.CharField(max_length=500)
op = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=None, blank=True, null=True)
date_created = models.DateTimeField(auto_now_add=True)
Post_Img = CloudinaryField('Post')
forms :
class PostImg(forms.ModelForm):
class Meta:
model = MemeImg
fields = ['Title', 'op', 'Post_Img']
view :
#login_required(login_url='/login')
def post(request):
func = data(request)
if request.method == 'POST':
form = PostImg(request.POST, request.FILES, instance=request.user)
form.op = request.user
if form.is_valid():
print('success')
posts = form.save(commit=False)
posts.op = request.user
form.save()
return HttpResponseRedirect('https://youtu.be/dQw4w9WgXcQ')
else:
print("fail")
form = PostImg(request)
ctx = {
'form': form,
'url': func[0],
'name': func[1],
'date': func[2],
}
return render(request, 'Post.html', ctx)
and finally the post page template :
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="container">
{{ form.Title|materializecss }}
<div class="file-field input-field">
<div class="btn">
<span>File</span>
<input type="file">
</div>
<div class="file-path-wrapper">
{{ form.Post_Img }}
<input class="file-path validate" type="text">
</div>
</div>
<button class="btn waves-effect waves-light" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
</div>
</form>
If anymore code is required please comment it
Thanks a lot
I think your problem come from the form instance which is instance=request.user, actually the instance is supposed to be the MemeImg object instance and not the user, that's making it not to save the image. So i have deleted the instance and also i don't know what you are using those extra context variable for 'url': func[0],'name': func[1], 'date': func[2] ?, so i deleted them too keep things simple. Now i think you should be able to save without any Issues.
#login_required(login_url='/login')
def post(request):
if request.method == 'POST':
form = PostImg(request.POST, request.FILES)
if form.is_valid():
print('success')
data = form.save(commit=False)
data.op = request.user
form.save()
return HttpResponseRedirect('https://youtu.be/dQw4w9WgXcQ')
else:
print("fail")
form = PostImg(request.POST)
ctx = {
'form': form,
}
return render(request, 'Post.html', ctx)
Also your form had in it {{ form.Post_Img }} which i don't no what you are looking to accomplish with that variables?, the right way is doing {{ form.as_p }} or simply just calling the form like this {{ form }} so i have made the correction in you HTML
too.
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="container">
{{ form.Title|materializecss }}
<div class="file-field input-field">
<div class="btn">
<span>File</span>
<input type="file">
</div>
<div class="file-path-wrapper">
{{ form }}
<input class="file-path validate" type="text">
</div>
</div>
<button class="btn waves-effect waves-light" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
</div>
</form>
I have two models with two different forms. One has a ForeignKey for another model, making a 1-N relationship. The problem is when i try to add images , is not working. The form where i change the (name/TabletForm2) is working so , only when i try to add (image/TabletFormImagem) is not working.
The problem is that
My model's
def get_image(instance, filename):
return os.path.join('intervencao/fotografias', str(instance.intervencao), filename)
class Intervencao(models.Model):
name= models.CharField(verbose_name="Name", max_length=200, blank=True, null=True)
class Imagem(models.Model):
intervencao = models.ForeignKey(Intervencao, related_name='intervencaoObjectsImagem', on_delete=models.CASCADE)
imagem = models.ImageField(upload_to=get_image, blank=True, null=True, verbose_name="Fotografia")
def __str__(self, ):
return str(self.intervencao)
My View
def project_detail_chefe(request, pk):
form = TabletForm2(request.POST)
form2 = TabletFormImagem(request.POST, request.FILES)
if request.method == "POST":
if form.is_valid():
form.save()
return redirect('index')
else:
form = TabletForm2(request.POST)
if form2.is_valid():
//when i print something here to see if the form2 is valid , never enter here.
form2.save()
return redirect('index')
else:
form2 = TabletFormImagem()
context = {
'form':form,
'form2':form2,
}
return render(request, 'tablet/info_chefes.html', context)
tablet/info_chefes.html
<div class="col-md-12">
<div class='form-group'>
<label for="{{ form.subject.id_for_label }}" id="titulo">Name:</label>
<em>{{ form.name}}</em>
</div>
</div>
<div class="col-md-12">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form2.as_p }}
<button type="submit">Upload</button>
</form>
</div>
Forms
class TabletForm2(forms.ModelForm):
class Meta:
model=Intervencao
fields = ['data_intervencao_fim','ferramenta']
class TabletFormImagem(forms.ModelForm):
class Meta:
model=Imagem
fields = ['imagem']
def project_detail_chefe(request, pk):
form = TabletForm2()
form2 = TabletFormImagem()
if request.method == "POST":
form = TabletForm2(request.POST)
form2 = TabletFormImagem(request.POST, request.FILES)
if form.is_valid() and form2.is_valid():
instance_form1 = form.save()
instance_form2 = form2.save(commit=False)
instance_form2.intervencao = instance_form1
instance_form2.save()
return redirect('index')
else:
form = TabletForm2()
form2 = TabletFormImagem()
context = {
'form':form,
'form2':form2,
}
return render(request, 'tablet/info_chefes.html', context)
HTML
<form method="post" enctype="multipart/form-data">
<div class="col-md-12">
<div class='form-group'>
<label for="{{ form.subject.id_for_label }}" id="titulo">Name:</label>
<em>{{ form.name}}</em>
</div>
</div>
<div class="col-md-12">
{% csrf_token %}
{{ form2.as_p }}
<button type="submit">Upload</button>
</div>
</form>
I have an image upload function in django. However, images cannot be uploaded. The page is redirected to successURL. I don't understand the cause.
The view is current because it uses multiple forms.
#view
def UserEdit(request):
if request.method == 'POST':
form = forms.UserUpdateForm(request.POST, instance=request.user)
subform = forms.ProfileUpdateForm(request.POST, instance=request.user.profile)
if all([form.is_valid(), subform.is_valid()]):
user = form.save()
profile = subform.save()
return redirect('person:myaccount', username=request.user)
else:
form = forms.UserUpdateForm(instance=request.user)
subform = forms.ProfileUpdateForm(instance=request.user.profile)
return render(request, 'accounts/accounts_edit.html', {
'form': form,
'subform': subform,
})
#form
class UserUpdateForm(forms.ModelForm):
#...
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = profile
fields = ('first_name','last_name','birthday','image',)
#model
class profile(models.Model):
image = models.ImageField(upload_to='profile/',default='profile/default.jpg')
#html
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="text-center col-lg-6 col-md-6 col-sm-10 mx-auto">
<div class="form-group">
{{ form }}
</div>
<div class="form-group">
{{ subform }}
</div>
<button type="submit" class="fadeIn fourth btn btn-light">Submit</button>
</div>
</form>
I have a view where they are multiple posts and I want when the user like one of them, the form take the user_id and the post_id and save it into the DB. This is th Models.py:
class LikePost(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Posts, on_delete=models.CASCADE)
def __str__(self):
return '{} - {}'.format(self.user.username, self.post.name)
Forms.py:
class LikePostForm(forms.ModelForm):
class Meta:
model = LikedShops
fields = ['user', 'post']
widgets = {
'user': forms.HiddenInput(),
'post': forms.HiddenInput()
}
Views.py:
def posts(request):
if request.method == 'POST':
form = LikePostForm(request.POST)
if form.is_valid():
u = form.save(commit=False)
u.user = request.user
u.save()
return redirect('posts')
else:
form = LikePostForm()
context = {
'posts': Posts.objects.all(),
'form': form
}
return render(request, "posts.html", context)
and this the form in posts.html:
{% for post in posts %}
<div class="col-md-3">
<article class="card mb-4">
<header class="card-header">
<h4 class="card-title"><b>{{ post.name }}</b></h4>
</header>
<img style="width: 100%; height: 150px;" class="card-img" src="{{ post.image.url }}"/>
<div class="card-body">
<p class="card-text">{{ post.description }}</p>
</div>
{% if user.is_authenticated %}
<div class="card-footer">
<div class="row">
<div class="col">
<form action="/posts/" method="post">
{% csrf_token %}
{{ l_form|crispy }}
<button type="submit" class="btn btn-outline-success">Like</button>
</form>
</div>
</div>
</div>
{% endif %}
</article><!-- /.card -->
</div>
{% endfor %}
This is my edit, I did what you said, I made changes to:
forms.py:
class Meta:
model = Liked
fields = ['user', 'post']
widgets = {
'user': forms.HiddenInput(),
'post': forms.HiddenInput()
}
posts.html:
<form action="/posts/" method="post">
{% csrf_token %}
<input type="hidden" name="post" value="{{ post.pk }}">
{{ l_form|crispy }}
<button type="submit" class="btn btn-outline-success">Like</button>
</form>
views.py:
def posts(request):
if request.method == 'POST':
l_form = LikePostForm(request.POST, instance=request.user.profile)
if l_form.is_valid():
u = l_form.save(commit=False)
u.post = Posts.objects.filter(pk=l_form.cleaned_data.get('post')).first()
u.save()
messages.success(request, f"Form is valid!")
else:
messages.warning(request, f'Form is not valid! {request.POST}')
else:
l_form = LikePostForm(instance=request.user.profile)
context = {
'post': Posts.objects.all(),
'l_form': l_form
}
return render(request, "posts.html", context)
Now when I click the Like button, I got this message **Form is not valid! <QueryDict: {'csrfmiddlewaretoken': ['cNk9ZDS33Nj0l95TBfwtedL1jjAbzDSrH15VjMNZAcxjQuihWNZzOkVnIyRzsjwN'], 'post': ['1', ''], 'user': ['1']}>**
There are a couple of issues with your code.
First, the __str__() method should return a string and not a tuple
class LikePost(models.Model):
...
def __str__(self):
return '{} - {}'.format(self.user.username, self.post.name)
Second, there is a typo; change Pots to Posts:
context = {
'posts': Posts.objects.all(),
'form': form,
}
return render(request, "posts.html", context)
And third and last, the line u.post = request.post is throwing the error you mention, because the request object has no attribute post.
So change your form code to add the post in hidden state (I used fields instead of exclude):
class LikePostForm(forms.ModelForm):
class Meta:
model = LikePost
fields = ['post', ]
widgets = {
'post': forms.HiddenInput(),
}
and then change your view:
form = LikePostForm(request.POST)
if form.is_valid():
u = form.save(commit=False)
u.user = request.user
u.save()
After edit to the question:
Try adding post.pk as a hidden input in your form:
<form action="/posts/" method="post">
{% csrf_token %}
<input type="hidden" name="post" value="{{ post.pk }}">
{{ l_form|crispy }}
<button type="submit" class="btn btn-outline-success">Like</button>
</form>
or you can also do in your view:
u.post = Posts.objects.filter(pk=form.cleaned_data.get('post')).first()
I have related model EntertainmentCollage with image fields and did't now how to transfer instance models to the editing form. I need to display the existing images in the editing form and have the ability to add new ones.
models.py
class Entertainment(models.Model):
main_photo = models.ImageField(upload_to = 'where/')
place = models.CharField(max_length=200)
description = models.CharField(max_length=200)
event_date = models.DateTimeField(auto_now_add=False, blank=True, null = True)
class EntertainmentCollage(models.Model):
img = models.ImageField(upload_to = 'entertainment/portfolio', blank = True)
album = models.ForeignKey(Entertainment, blank = True, null = True)
views.py
def edit_where(request, pk):
place = Entertainment.objects.get(id=pk)
FormSet2 = inlineformset_factory(Entertainment, EntertainmentCollage, fields =['img',], extra=6)
form = WhereCreateForm(instance=place)
form2 = FormSet2()
if request.user.is_authenticated():
if request.method == "POST":
form = WhereCreateForm(request.POST, request.FILES, instance=place)
if form.is_valid():
form2 = FormSet2(request.POST or None, request.FILES)
if form2.is_valid():
form.save()
form2.save()
return redirect('entertainment:where_list')
else:
form = WhereCreateForm()
form2 = FormSet2()
return render(request, "entertainment/where_edit.html", {'form': form, 'form2': form2})
html
<section>
<div class="container">
<div class="row">
<div class="col-md-3">
<h2>Editing Where</h2>
<br>
<form method = "post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.eventname }}</p>
<p>{{ form.place }}</p>
<p>{{ form.event_date }}</p>
</div>
<div class="col-md-9">
<section class="admin-section">
{{ form2.management_form }}
<div class="row">
{% for frm in form2 %}
<div class="col-md-4 admin__block" is-cover="false">
<div class="cover__wrapper edit__wrapper">
<a class="delete-button">Delete</a>
<a class="make-cover-button">Cover</a>
<img src="{{ frm.url }}" alt="">
</div>
</div>
{% endfor %}
</div>
Add photo
</section>
<section>
<h4>Description</h4>
{{ form.description }}
<input type="submit" value="Save">
Cancel
</section>
</form>
</div>
</div>
</div>
</section>
If I try to add
collage = EntertainmentCollage.objects.filter(album = place)
to my views.py and make form2(instance = collage) error occured QuerySet' object has no attribute 'pk'
___ UPDATE ___
I need to get page like http://joxi.ru/Dr8X8w4tkGw1zr
where images are taken from the model EntertainmentCollage,
and if they are added then I could see them in the form.
I realized that my question was incorrectly asked. I just had to display all the images from the queryset and use the inline form to add a button to add a new image.