I am trying to update Profile photo with Django
According to yt tutorials I created form for updating photo:
class UserProfileForm(forms.ModelForm):
class Meta:
model = User_Model
fields = ["profile_photo"]
And this is my class to Change photo in views:
class UpdatePhoto(TemplateView):
template_name = "Messenger/update_photo.html"
profile_form = UserProfileForm
def post(self, response):
data = response.POST
file_data = response.FILES
profile_form = UserProfileForm(data, file_data, instance=response.user.profile)
if profile_form.is_valid():
profile_form.save()
return redirect("/")
print("rere")
context = self.get_context_data(profile_form=profile_form)
return self.render_to_response(context)
My Model:
class User_Model(models.Model):
user = models.OneToOneField(
User, null=True, on_delete=models.CASCADE, related_name="profile"
)
profile_photo = models.ImageField(
upload_to="images/", default="default_photo.jpg", null=True, blank=True
)
chats = models.ManyToManyField(User, related_name="chats", blank=True)
blocked_list = models.ManyToManyField(User, related_name="blocked_list", blank=True)
I was trying with and without 'response.POST', result was the same, it does not update. However when I try to print 'file_data' I get something like this:
<MultiValueDict: {'Browser': [<InMemoryUploadedFile: thumb.jpg (image/jpeg)>]}>
Main Settings.py:
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = "static/"
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
And main urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("Messenger.urls")),
] static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
App urls:
from django.urls import path
from django.contrib.auth.decorators import login_required
from . import views
urlpatterns = [
path(
"",
login_required(views.Chat_list_Usernames.as_view(), login_url="/login"),
name="home",
),
path(
"change_status/",
login_required(views.change_status, login_url="/login"),
name="change_status",
),
path("login/", views.login_page, name="login_page"),
path(
"logout/", login_required(views.logout_user, login_url="/login"), name="logout"
),
path("register/", views.register_page, name="register_page"),
path(
"update_photo/",
login_required(views.UpdatePhoto.as_view(), login_url="/login"),
name="update_photo",
),
path(
"change_password/",
login_required(views.ChangePassword.as_view(), login_url="/login"),
name="change_password",
),
path(
"send_message/",
login_required(views.SendMessage.as_view(), login_url="/login"),
name="send_message",
),
]
And my template:
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/update_photo.css'%}">
<div >
<div >Change</div>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div >
<div >
<input id="files" required type="file" name="Browser"
accept="image/png, image/jpeg, image/jpg, image/webp">
</div>
<div >
<div >
<a href="{% url 'home'%}"><input type="button" name="Back" , value="Back"></a>
</div>
<div >
<input type="submit" name="Change" , value="Change">
</div>
</div>
</form>
</div>
Also I need to mention that I can update photo though admin panel but it's how this should work .
I Have no idea what have I done wrong and how to make it work right.
CodePudding user response:
You should use UpdateView
instead of TemplateView
as it only renders a given template, with the context containing parameters captured in the URL.