Django Image Upload, Image Is Never Stored - python

I'm having some trouble with a django blog that I'm working on, and I was wondering if someone could help me out.
https://github.com/kevin-reaves/Blog
localhost:8000/posts/create
Basically, when I go to create a blog post using the creation form everything seems to work aside from uploading the actual image. The admin console seems to think there's an image at the correct location, but nothing gets uploaded there.
Here's the password for the admin console
admin
password123
Edit: Added some relevant code
<form action="{% url 'create' %}" method="POST">{% csrf_token %}
<p>Title:</p>
<input type="text" name="title"/>
<br/>
<p>Image:</p>
<input type="file" name="image"/>
def create(request):
if request.method == 'POST':
if request.POST['title'] and request.POST['body']:
post = Post()
post.title = request.POST['title']
post.pub_date = timezone.datetime.now()
post.image = request.POST['image']
post.body = request.POST['body']
post.author = request.user
post.save()
return redirect('home')
class Post(models.Model):
title = models.CharField(max_length=250)
pub_date = models.DateTimeField()
author = models.ForeignKey(User, db_column="user", default=1)
image = models.FileField(upload_to='media', blank=True)
body = HTMLField()

Quick find... you need two changes this to work.
Add enctype="multipart/form-data" in your html form
use request.FILES['image']

Related

Creating simple like button

Hi im developping a blog app and i am creating a simple like button for the post idintified by it's pk where the link is located in a form but it ran into an error.
NoReverseMatch at /single_post/8/
Reverse for 'like_post' not found. 'like_post' is not a valid view function or pattern name.
my views.py for the detail view and the like button view
def post_detail(request, pk):
post = Post.objects.get(id=pk)
context = {
'post': post,
}
return render(request, 'news/post_detail.html', context)
def LikeView(request, pk):
post = get_object_or_404(Post, id=request.POST.get('post_id'))
post.likes.add(request.user)
return(HttpResponseRedirect(reverse('single_post', args=[str(pk)] )))
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
image = models.ImageField(upload_to='img/', default='img/default.jpg')
author = models.CharField(max_length=100)
date = models.DateTimeField(auto_now_add=True)
credit = models.URLField(blank=True, null=True)
likes = models.ManyToManyField(User, related_name='daily_posts')
def __str__(self):
return self.title
in the detail views the form and the link
<form action="**{% url 'like_post' post.pk %}**" method="POST">
{% csrf_token %}
<button class="btn btn-primary btn-sm" type="submit", name="post_id", value="{{ post.id }}">Like</button>
</form>
and the error i run to everytime i hit like.
NoReverseMatch at /single_post/8/
Reverse for 'like_post' not found. 'like_post' is not a valid view function or pattern name.
i cannot identify what seems to be the issue here anyone can help please?
In LikeView, you reverse 'single_post' but in the form you have 'like_post'. Perhaps change 'single_post' in LikeView to 'like_post'? EDIT FOR NAMESPACE: I believe you need to include the namespace in the form i.e. {% url 'news:like_post' post.pk %}

Django Inline formsets always invalid

I am struck with inline formsets in Django. Each time I submit the formset it is considered invalid and hence the data doesn't get saved. I am a newbie in full-stack development and am learning Django. I am following Dennis Ivy's playlist on youtube and coding along with him. It is kind of an E-commerce portal where people can order stuff. Here is a link to the video where he implements inline formsets Video. It was working fine when I accepted orders through normal form i.e. one order at a time. I have done exactly as he did in his video. I also tried consulting my friends who are learning with me and also asked my mentor about it but no one could figure out what is wrong here. I browsed through the documentation but that too didn't help. Please help me out in fixing this.
Github Repo link
views.py
from django.forms import inlineformset_factory
def createOrder(request, pkCrteOrder):
OrderFormSet = inlineformset_factory(customer, order, fields=('product','status'), extra=7)
CustomerOrderOwner = customer.objects.get(id=pkCrteOrder)
formSet = OrderFormSet(queryset = order.objects.none(), instance=CustomerOrderOwner)
if(request.method == 'POST'):
print("post request detected")
formSet = OrderFormSet(request.POST, instance=CustomerOrderOwner)
if formSet.is_valid():
formSet.save()
return(redirect('/'))
else:
print("formset was invalid")
context = {'formSet': formSet}
return(render(request, 'accounts/orderForm.html', context))
Brief explaination: From a particular customer's page we can place order. So pkCrteOrder represents the id of customer. I fetch the customer and pass it as instance for the formset and then send the formset to template. If form is submitted I check if it's valid and then save else i print "formset was invalid"
order model:
class order(models.Model):
STATUS = (
('Pending', 'Pending'),
('Out for delivery', 'Out for delivery'),
('Delivered', 'Delivered'),
)
customer = models.ForeignKey(customer, null = True, on_delete=models.SET_NULL)
product = models.ForeignKey(products, null = True, on_delete=models.SET_NULL)
date_created = models.DateTimeField(auto_now_add = True, null=True)
status = models.CharField(max_length=200, null=True, choices=STATUS)
template:
{% extends 'accounts/base.html' %} {% load static %} {% block content %}
<div class="row">
<div class="col-md-6">
<div class="card card-body">
<form method="POST" action="">
{% csrf_token %}
{{formset.management_form}}
{% for form in formSet %}
{{form}}
<hr />
{% endfor %}
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock content %}
Thank you
In your template you have {{formset.management_form}}. But really the variable containing the forms you are sending from the view is called fromSet (notice the capital S). So change that code into {{formSet.management_form}} and it should work fine.

How to update profile picture for existing model instance?

I'm trying to update a user's profile photo after they've already created their account. I'm using an abstract user model connected to a model called Person. For additional context, I have my application connected to AWS to deploy to Heroku.
I have a form, model, url and view set up but I'm sure I'm missing some piece to the puzzle.
<form action="{% url 'update-photo' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table class="table-form">
{{ form|crispy }}
</table>
<input type="submit" class="btn btn-lg custom-bg">
<br><br>
</form>
class User(AbstractUser):
is_active = models.BooleanField(default=False)
class Person(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
upload = models.FileField(default='core/static/images/default_avatar.png')
class UpdatePhotoForm(forms.ModelForm):
class Meta:
model = Person
fields = ('upload',)
#login_required
def update_photo(request):
person = Person.objects.get(user=request.user)
from core.forms import UpdatePhotoForm
if request.method == "POST":
form = UpdatePhotoForm(data=request.POST, instance=request.user.person)
if form.is_valid():
person = form.save(commit=False)
person.save()
return redirect('profile')
else:
form = UpdatePhotoForm()
return render(request, 'core/edit_profile.html', {'form': form})
path('update_photo/', core_views.update_photo, name='update-photo'),
The form submits without any error but does not actually update the user's photo. I can change the photo in the admin site but not via the form. Any help would be greatly appreciated!
You will have to fetch file field from request Object with following code:
form = UpdatePhotoForm(data=request.POST, files=request.FILES, instance=request.user.person)

Django - Query To Check if Item In Many to Many Relationship Field

I have a User and a Deal model as shown below. The User model has a 'favorites' field which is a many to many relationship with the Deal model.
I'm trying to allow a user to save a Deal to their Favorites. I have tested both the favorite and remove_favorite views and both are doing exactly what they are supposed to do.
Here's My Issue -- The conditional statement on my deal_detail.html page which checks to see if the current deal on the page is a favorite of the logged in user doesn't seem to be working.
{% if deal_detail in user.favorites %}
I'm just having a hard time wrapping my head around how to check this.
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, error_messages={'unique':"This email has already been registered."})
username = models.CharField(max_length=40, default='')
first_name = models.CharField(max_length=40, default='', blank=True)
last_name = models.CharField(max_length=40, default='', blank=True)
date_joined = models.DateTimeField(default=timezone.now)
favorites = models.ManyToManyField(Deal, related_name='favorited_by', null=True, blank=True)
class Deal(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=140, unique=True)
description = models.TextField(default='')
My corresponding views look like this:
def deal_by_detail(request, slug):
deal_detail = Deal.objects.get(slug=slug)
user = request.user
return render(request, 'deals/deal_detail.html', {'deal_detail': deal_detail, 'user': user})
#login_required(login_url='/accounts/sign_in/')
def favorite(request, pk):
if request.method == 'POST':
favorite = Deal.objects.get(pk=pk)
user = request.user
user.favorites.add(favorite)
messages.add_message(request, messages.INFO, 'Deal Favorited.')
return redirect('home')
#login_required(login_url='/accounts/sign_in/')
def remove_favorite(request, pk):
if request.method == 'POST':
favorite = Deal.objects.get(pk=pk)
user = request.user
user.favorites.remove(favorite)
messages.add_message(request, messages.INFO, 'Deal Removed.')
return redirect('home')
My form deal_detail.html looks like this:
{% if deal_detail in user.favorites %}
<form id="favorite{{deal_detail.id}}" method="POST" action="{% url 'deals:favorite' deal_detail.id %}">
{% csrf_token %}
<input type="hidden" name="supporttype" />
<input type="submit" value="Add Deal to Favorites" />
</form>
{% else %}
<form id="favorite{{deal_detail.id}}" method="POST" action="{% url 'deals:remove_favorite' deal_detail.id %}">
{% csrf_token %}
<input type="hidden" name="supporttype" />
<input type="submit" value="Remove Deal From Favorites" />
</form>
{% endif %}
I believe you are just missing the .all after the manytomany field. Then it should be able to run the check and function as you intended
{% if deal_detail in user.favorites.all %}

Validation Error Django Form

Hey so I set up a input form for users to share projects they are working on on a website I have been developing in Django 1.5, I created model, view and Form Model, to allow users who are logged in to add links to projects they are working on.
The Model works and when I enter a text through the admin panel it creates a new object, the views all seem to work, the form loads, and seems to take input however, the Project Name field keeps throwing me a invalid input error when I attempt to fill out the form, not sure why because I am inputing a string, and the field is designated as a CharField in both the Model, and Form Model.
Model:
class Project(models.Model):
creator = models.ForeignKey(User)
project_name = models.CharField(max_length=128)
website = models.URLField(blank=True)
github = models.URLField(blank=True)
description = models.CharField(max_length=255, unique=True)
likes = models.IntegerField(default=0)
def __unicode__(self):
return self.nam
View for adding a project:
#login_required
def add_project(request):
context = RequestContext(request)
if request.method == 'POST':
form = ProjectForm(request.POST)
if form.is_valid():
form.save(commit=False)
project.creator = request.user
project.save()
return index(request)
else:
print form.errors
else:
form = ProjectForm()
return render_to_response('rango/add_project.html', {'form' : form}, context)
The Form Model:
class ProjectForm(forms.ModelForm):
project_name = forms.CharField(max_length=128, help_text="What is the name of your project?")
website = forms.CharField(max_length=200, help_text="Enter the project website:")
github = forms.CharField(max_length=200, help_text="Enter the project github:")
description = forms.CharField(widget=forms.Textarea, help_text="Description:")
likes = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
class Meta:
model = Project
exclude = ('creator')
def clean(self):
cleaned_data = self.cleaned_data
website = cleaned_data.get('website')
#If Url is not empty and dont start with 'http://' prepend 'http://'
if website and not website.startswith('http://'):
website = 'http://' + website
cleaned_data['website'] = website
return cleaned_data
def clean(self):
cleaned_data = self.cleaned_data
github = cleaned_data.get('github')
#If Url is not empty and dont start with 'http://' prepend 'http://'
if github and not github.startswith('http://'):
github = 'http://' + github
cleaned_data['github'] = github
return cleaned_data
and lastly the html template:
{% extends 'rango/base.html' %}
{% block title %} Add Project {% endblock %}
{% block body_block %}
<H1>Add a new Project</H1>
<form id="project_form" method="post" action="/rango/add_project/">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{hidden}}
{% endfor %}
{% for field in form.visible_fields %}
{{field.errors}}
{{field.help_text}}
{{field}}
{% endfor %}
<input type="submit" name="submit" value="Create Project" />
</form>
{% endblock %}
The Page loads fine but when I attempt to submit i get this for project name:
Enter a valid value.
the value I entered was test for project name.
In the view function, I do not understand from where project comes from.
I would expect instead:
project = form.save(commit=False)
project.creator = request.user
project.save()

Categories