PYTHON-DJANGO-BLOG PROJE ÇALIŞMASI 9 ( update işlemleri-profil bilgi güncelleme-değiştirme)

 Bir önceki yayında kullanıcı hesabı oluştuğunda(register form-register sayfası ile)  o kullanıcıya özel bir profilin de oluşturulması aşamasını gördük. Şimdi bu profili biraz daha geliştirelim. Oluşturulan profilde değişiklik yapılasını sağlayan yani Profil resmini ekleme-güncelleme ve profil resminin resize( yeniden boyutlandırma gibi işemleri) işlemlerini görelim.

Bu işlemler için aşağıdaki adımları izleyin.

1. users app- forms.py dosyasına geçin aşağıdaki kodları ekleyin:

from .models import Profile #bu satırı kodunuzda üste ekleyin
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField() # default bıraktık zorunlu alan gibi davranır

class Meta:
model = User
fields = ['username', 'email']


class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
field = ['image']
Yukarıdaki kodda bir model form oluşturuldu. Bu model form belirli bir veritabanı modeliyle çalışacak ve burada oluşturduğumuz form modeli bizim user modeli update ( kullanıcı modelini güncellemeyi) etmeyi sağlayacak. Bu işlem için class UserUpdateForm( forms.Modelform ) sınıf temelli komutu eklendi. Bu komutla UserRegisterForm sınıfı ile benziyor. Ancak burda password bilgisi kullanılmayacak. Bu neden Password ile ilgili kısım kaldırıldı.

2. Şimdi oluşturulan bu formun views.py de görünümünün ayarlanmasına(import edilmesine-1. adımda UserUpdateForm, ProfileUpdateForm hazırlanmıştık) sıra geldi. Bunun  için users app -views.py dosyasını açın.

users app-views.py:

a. Öncelikle oluşturduğumuz formları(UserUpdateForm, ProfileUpdateForm) import eden komutu ekleyelim.

from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm

b. Oluşturduğumuz formları kullanılması için context ile profil.html sayfasına görülmesini sağlayan kodları ekleyelim.

@login_required
def profile(request):
usr_form = UserUpdateForm()
prfl_form = ProfileUpdateForm()

context = {
'usr_form': usr_form,
'prfl_form': prfl_form
}
return render(request, context,'users/profile.html')

3. Sırada profile.html dosyasına usr_form ve prfl_form bilgilerinin yerleştirilmesi var. Aşağıdaki kodları hemen {% endblock %} etiketinden önceki alana ekleyebilirsiniz. 

(Ayrıca bu kodları register.html dosyasından <form method="POST" ile başlayan satır ile ......</form> etiketi aralığındaki kodları kopyalayabilir kullanablirsiniz. )

 <form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Profil Bilgileri</legend>
{{ usr_form|crispy }}
{{ prfl_form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Güncelle-update</button>

</div>
</form>

</div>
{% endblock %}
Kodda crispy form kullanıldığına dikkat edin bu neden profile.html dökümanınızda en üstlerde
 {% load crispy_forms_tags %}  kod satırının profile.html de bulunduğuna emin olun.

Kodda {{ usr_form|crispy }} ve  {{ prfl_form|crispy }} adında iki tane form bilgisi dinamik olarak profil sayfasına çekildiğine dikkat ediniz.

Kodda {{ usr_form|crispy }} ve  {{ prfl_form|crispy }} adında iki tane form bilgisi var o yüzden crispy etiketi aşağıdaki gibi iki tane profile.html sayfasına eklendiğine dikkat edin.
{{ usr_form|crispy }}
{{ prfl_form|crispy }}
Bu profile.html sayfası register.html sayfasına benzediği için o sayfayı değiştirerek kullandığımızı bir kere daha hatırlatalım. Dolayısıyla bazı kısımları profile.html sayfasına uygun hale getirildi.

NOT:
Kodda (1. satırdaki etikette geçen <form method="POST" enctype="multipart/form-data"> ) geçen  enctype="multipart/form-data" özelliği ASCII olmayan verilerin gönderilmesi için kullanılır başka bir deyişle dosya veya resim  yükleme gibi.
( form ile resim gönderme için gerekli özellik tanımlanmış oldu.)

Şimdi RUNSERVER diyip sitenizi test edebilir ve profile.html sayfanızın doğru çalıştığını görebilirsiniz. 

4.  Sayfanız çalışıyor ama henüz login olmuş kullanıcın profile.html sayfasında profil bilgileri görünmesi gerekir ama görünmüyor. Şimdi bu eksikliği gidermeye çalışalım.

users app-views.py dosyasına geçin :

a. O anki login olmuş kullanıcının profil bilgilerine girdiğinde var olan bilgileri kullanıcıya görünmesi için var olan kodlarınıza 
 instance=request.user ve instance=request.user.profile kodlarını aşağıdaki gibi ekleyin.

@login_required
def profile(request):
usr_form = UserUpdateForm(instance=request.user)
prfl_form = ProfileUpdateForm(instance=request.user.profile)

context = {
'usr_form': usr_form,
'prfl_form': prfl_form
}
return render(request, 'users/profile.html', context)
b. Şimdi kişi profiline girdiğinde EĞER birşeyi POST etti mi diye kontrol etmek gerekir bunun için if yapısı kullanalım. Gerekli kod aşağıdaki gibidir.

@login_required
def profile(request):
if request.method == 'POST':
usr_form = UserUpdateForm(request.POST, instance=request.user)
prfl_form = ProfileUpdateForm(request.POST,
request.FILES,
instance=request.user.profile)
if usr_form.is_valid() and prfl_form.is_valid():
usr_form.save()
prfl_form.save()
messages.success(request, f' hesabınız güncellendi.')
return redirect('profile')
else:
usr_form = UserUpdateForm(instance=request.user)
prfl_form = ProfileUpdateForm(instance=request.user.profile)

İkinci bir if yapısı kullanıldığına dikkat edin. Bu if kullanımında  user ve profil isimli formların ikisi de GEÇERLİ( is_valid ) olup olmadığı kontrol edecek -yani burda kayıtlı bir kullanıcı adı girilirse onu uyaracak - girilen değerler geçerli ise user ve profil formlarını kaydecek. ( usr_form.save() ve prfl_form.save())

c. 
users app-views.py dosyasının son hali aşağıdaki gibidir :


from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm


# Create your views here.

def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f' hesabınız tanımlandı. Artık giriş yapabilirsiniz.')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})

@login_required
def profile(request):
if request.method == 'POST':
usr_form = UserUpdateForm(request.POST, instance=request.user)
prfl_form = ProfileUpdateForm(request.POST,
request.FILES,
instance=request.user.profile)
if usr_form.is_valid() and prfl_form.is_valid():
usr_form.save()
prfl_form.save()
messages.success(request, f' hesabınız güncellendi.')
return redirect('profile')
else:
usr_form = UserUpdateForm(instance=request.user)
prfl_form = ProfileUpdateForm(instance=request.user.profile)



context = {
'usr_form': usr_form,
'prfl_form': prfl_form
}
return render(request, 'users/profile.html', context)

5. Şimdi de profil resmi güncellemesi yapıldığında yüklenen resmin otomatik olarak yeniden boyutlandırılmasını(resize) sağlayacağız. Yüklenen resmin kullancıya gçsterilme büyüklüğü CSS ile ayarlanmışı ancak gerçek yüklenen resmin de otomatik küçüktülmesi yer kaplamsını azaltır ve sitenin açılma hızını olumlu etkiler. Bunu yapmak için aşağıdaki adımları dikkatli takip edin.

users app- models.py dosyasına gir:

a. Diyelimki kullanıcı daha önce yüksek boyutlu resim yükledi bunu değiştirmek için aşağıdaki kodu kullanırız.
def save(self):
super().save()

b. Şimdide yükelenen resmin resize edilmesi gerekir bunun için pillow library(PIL) kullanılacak bunun için import edilmesi gerekir. Aşağıdaki kodu üst alana ekleyin.

from PIL import Image
c. Şimdide resmin o anki yani güncelleme sırasaındaki örneğini instance alır. ( örneği oluşturalım) Komut ise aşağıdadır.
img = Image.open(self.image.path)
d. Şimdi de resize yapılacak resim 300px den büyükse resize uygulamayı sağlayacak kodları ekleyelim.
Kodda geçen self.image.path komutu ile kaydetme işlemini üzerine(everride save metod of model örneği yapılmış oldu) yapacak.
if img.height >300 or img.width >300:
output_size= (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
e. Şmdi de buraya kadar eklenen kodlarla birlikte sayfamızı test edebiliriz.

users app - model.py nin sonhali:

from django.db import models
from django.contrib.auth.models import User
from PIL import Image
# Create your models here.

class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profil_resmi')

def __str__(self):
return f'{self.user.username} Profile'

def save(self):
super().save()

img = Image.open(self.image.path)

if img.height >300 or img.width >300:
output_size= (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)

f. Şimdi de bu profil resminin sitemizde anasayfada kullanıcı bir şey paylaştığında kullanıya ait profil resminin de görünmesini sağlayalım. Bu işlemler için sırayla aşağıdaki adımları yapalım

* blog app-home.html dosyasını açın ve aşağıdaki kodu ekleyin:

<img class="rounded-circle" width="60" height="60" 
 src="{{ post.author.profile.image.url }}">
** Şimdi de home.html dosyamızın son halini ekleyelim.


{% extends 'blog/base.html' %}
{% block content %}
{% for post in postsA %}
<div class="container">

<img class="rounded-circle" width="60" height="60" src="{{ post.author.profile.image.url }}">
<div class="card-header-pills">
<div class="card-header">
<div>
<a class="mr-2" href="#" >{{ post.author }}</a>
<small class="text-muted">{{ post.date_posted|date:"F d, Y"}}</small>
</div>
<h1><a class="card-title" href="#" >{{ post.title }}</a></h1>
<p class="card-body"> {{ post.content }} </p>
<p>{{ post.content }}</p>
</div>
</div>
</div>
{% endfor %}
{% endblock %}

Bu makalede kullanıcının profil bilgisini ve profil resmini güncellemesi ile ilgili işlemlerin nasıl yapıldığını anlatmaya çalıştık.




Yorum Gönder

0 Yorumlar