Django Image upload not POSTing - django

I am trying to let a user upload and change their picture.
Currently the form displays the current picture for the user without any issues, but I seem to have messed something when it comes to the upload part since the upload is not working (no error messages).
Also, is it possible to create a custom image form? Currently, this makes use of Djangos default one which is not that style-friendly.
Views.py
#login_required
def edit(request):
if request.method == "POST":
FormImage= UserProfileForm(request.POST, request.FILES, instance=request.user)
if FormImage.is_valid():
FormImage.account_id = request.user.id
FormImage.save()
return HttpResponseRedirect(request.path_info)
else:
imageForm = UserProfileForm(instance=request.user)
return render(request, 'accounts/info.html', {
"FormImage": FormImage,
})
Forms.py
class UserProfileForm(UserChangeForm):
FRUIT_CHOICES = (
('Banana', 'Banana'),
('Orange', 'Orange'),
('Apple', 'Apple'),
)
fruits = forms.CharField(widget=forms.Select(choices=FRUIT_CHOICES))
class Meta:
model = Account
fields = (
'fruits',
'profile_picture',
)
Template
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
<label class="col-lg-3 col-form-label form-coantrol-label">Change picture</label>
<div class="col-lg-9">
{{ FormImage.profile_picture }}
</div>
<div class="form-group row">
<div class="container"><input class="btn btn-primary" type="submit" value="Save profile"></div>
</div>
</form>
My model field for profile pic
profile_picture = models.ImageField(default="default.png", null=True, blank=True)

Related

I am trying to get POST request but django response with GET request

I am trying to get the post request and i have tried everything it is still getting me get requests.
Please Help.
I have tried using that i saw in other problems displayed here. but it is not working for me.
{% csrf_token%}
Item name
{{form.item_name}}
Quantity
{{form.quantity}}
<div class="form-group">
<label for="address">Address</label>
{{form.address}}
</div>
<div class="modal-footer d-flex justify-content-center">
<button type="submit" id="submit" class="btn btn-success" data-dismiss="modal" >Donate</button>
</div>
</form>
This is my view file
#this is my view
#login_required(login_url='loginPage')
def home(request):
form = DonateForm()
print(request.user.id)
get_user = user_info.objects.get(id=request.user.id)
print('Inside Home View')
print(get_user)
print(request)
if request.method == 'POST':
form = DonateForm(request.POST)
print('Inside Home Page')
if form.is_valid():
print('Form is valid!!')
user = form.save()
Donate.objects.create(user_name = user,item_name=form.cleaned_data['item'],quantity=form.cleaned_data['itemquantity'])
else:
messages.add_message(request,messages.INFO,'Your details are Incorrect!!')
else:
print('No Post Request!!')
return render(request,'donate/home.html',{'form':form,'get_user':get_user})
Here is my Models.py
class Donate(models.Model):
user_name = models.ForeignKey(user_info,on_delete=models.CASCADE)
item_name = models.CharField(max_length=30,null=False , blank=False, default ="None")
quantity = models.IntegerField(null=False,blank=False,default=0)
address = models.CharField(max_length=100 , null=False , blank= False, default="None")
def __str__(self):
return f"{self.user_name.user.username} donated {self.item_name}"
Please try to add the method in the <form>, like this:
<form method="post" action="#">
{% csrf_token %}
......
<button type="submit" id="submit" class="btn btn-success" data-dismiss="modal" >Donate</button>
</form>

User form foreignkeyfield form not valid

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>

Django form gets image data but not text

I have Django form that displays information about the property and the idea of this form is to allow users to amend information about their properties. When displaying the form only image data is displayed, everything else is blank. From if request.user.landlord_profile.landlord_id == project.landlord_id: is the code for the form.
views.py
def project_detail(request, pk):
project = Properties.objects.get(pk=pk)
applyButton = Property_Applications.objects.filter(listing=project)
propertyReview = Property_Reviews.objects.filter(property=project)
# getting the urls
property_images = Property_Images.objects.filter(property=project)
context = {
'project': project,
'propertyReview': propertyReview,
'property_images' : property_images,
}
if request.user.is_authenticated:
if request.user.last_name == 'False': # allows to tenant to view ads and apply for them if they meet the requirements
tenant_profile = Tenant_Profile.objects.get(tenant=request.user.tenant_profile.tenant_id)
if request.method == "POST":
applyButton = Property_Applications(
user=request.user,
listing=project,)
applyButton.save()
context['applyButton'] = applyButton
context['tenant_profile']= tenant_profile
if request.user.landlord_profile.landlord_id == project.landlord_id: # if the landlord owns this ad, this let's him edit the ad
change_listing_form = ManageListingForm(request.POST, request.FILES, instance=project)
if request.method == 'POST':
if change_listing_form.is_valid():
change_listing_form.landlord = request.user.landlord_profile
change_listing_form.save()
messages.success(request, f'Your account has been updated!')
else:
change_listing_form = ManageListingForm()
context['change_listing_form'] = change_listing_form
return render(request, 'project_detail.html', context)
forms.py - ManageListingForm
class ManageListingForm(forms.ModelForm):
class Meta:
model = Properties
fields = ['description','rentPrice','tenantSalary','referenceRequired','image']
project_detail.html - this is what displays the form
{% elif request.user.landlord_profile.landlord_id == project.landlord_id%}
<p></p>
<div style="text-align: center">
<button class="open-button" onclick="openForm()">Manage your Spot</button>
</div>
<div class="form-popup" id="myForm">
<form class="form-container text-dark" method="POST" enctype="multipart/form-data">
<label for="Viewing Date " class="text-white">Enter a time that suits you to host a viewing with {{ portal.tenant }}</label>
<fieldset class="form-group col-md-12 bg-white border border-dark" style="margin: auto;padding: 10px">
{% csrf_token %}
{{change_listing_form | crispy}}
<div class="text-center">
<button type="submit" class="btn bg-dark text-white">Update your listing</button>
</div>
</fieldset>
<p></p>
<button type="button" class="btn cancel" onclick="closeForm()">Close</button>
</form>
<!-- Manage Listing function if the user is the owner-->
</div>
{% endif %}
Image of the the form only display image data
test install !!(pillow for images )
pip install pillow
default = just to look images at save it or another problem !
upload_to = destination file to load your images
in Model.py
image = models.ImageField(upload_to='put Your folder her ', default='default.png',)

django images cannot be updated from defaults

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>

django - pass multiple instance into form and save it in DB

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()