بهروزرسانی داده (Django Update Data)
بهروزرسانی داده: تغییر اطلاعات موجود 🔄
گاهی نیاز داریم اطلاعات موجود در دیتابیس رو تغییر بدیم. جنگو دو روش اصلی برای این کار داره که هر کدوم کاربرد خاص خودش رو داره.
روش اول: استفاده از save()
این روش وقتی استفاده میشه که میخواید یک رکورد خاص رو تغییر بدید:
# آپدیت با استفاده از save()
post = Post.objects.get(id=1)
post.title = "عنوان جدید"
post.content = "محتوا جدید"
post.save()
save() استفاده میکنید، جنگو تمام فیلدها رو آپدیت میکنه (حتی اونهایی که تغییر نکردن). این کار برای رکوردهای کوچک مشکلی نداره، ولی برای رکوردهای بزرگ ممکنه کند باشه.
روش دوم: استفاده از update()
این روش برای آپدیت چندین رکورد به صورت یکجا استفاده میشه و خیلی سریعتره:
# آپدیت مستقیم (سریعتر)
Post.objects.filter(id=1).update(title="عنوان جدید")
# آپدیت چندین رکورد
Post.objects.filter(published=False).update(published=True)
مزایای update():
- سریعتر: مستقیماً SQL UPDATE رو اجرا میکنه
- کارآمدتر: فقط فیلدهای مشخص شده رو آپدیت میکنه
- قدرتمند: میتونه چندین رکورد رو یکجا آپدیت کنه
آپدیت شرطی
میتونید فقط رکوردهایی رو آپدیت کنید که شرایط خاصی دارن:
# آپدیت فقط پستهای منتشر نشده
Post.objects.filter(published=False).update(published=True)
# آپدیت پستهای یک نویسنده خاص
Post.objects.filter(author=user).update(views=0)
# آپدیت با چندین شرط
from datetime import datetime, timedelta
yesterday = datetime.now() - timedelta(days=1)
Post.objects.filter(
created_at__lt=yesterday,
published=False
).update(published=True)
save() استفاده کنید. برای آپدیت چندین رکورد، حتماً از update() استفاده کنید تا عملکرد بهتری داشته باشید.
update() signal های مدل (مثل pre_save یا post_save) رو اجرا نمیکنه. اگر به این signal ها نیاز دارید، باید از save() استفاده کنید.
🎯 تمرین عملی:
تمام پستهایی که قبل از یک هفته پیش ساخته شدن رو پیدا کنید و اونها رو به عنوان "قدیمی" علامتگذاری کنید (یک فیلد is_old اضافه کنید و True کنید).
تمرینهای عملی
برای تثبیت یادگیری این درس تمرینهای زیر را حل کنید
🎯 تمرین عملی: آپدیت هوشمند
در این تمرین، یک سیستم آپدیت میسازیم که:
- تمام پستهای قدیمیتر از 30 روز رو پیدا کنه
- اونها رو به عنوان "archived" علامتگذاری کنه
- تعداد view های اونها رو صفر کنه
راهنمایی: از filter() و update() استفاده کنید. برای تاریخ از datetime و timedelta کمک بگیرید.
from django.db import models
from datetime import datetime, timedelta
# فرض کنید این مدل از قبل تعریف شده
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
views = models.IntegerField(default=0)
is_archived = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
def archive_old_posts():
# محاسبه تاریخ 30 روز پیش
thirty_days_ago = datetime.now() - timedelta(days=30)
# پیدا کردن و آپدیت پستهای قدیمی
count = Post.objects.filter(
created_at__lt=thirty_days_ago,
is_archived=False
).update(
is_archived=True,
views=0
)
return count
if __name__ == "__main__":
archived_count = archive_old_posts()
print(f"تعداد پستهای آرشیو شده: {archived_count}")
آماده رفتن به درس بعدی هستید؟
این درس را به پایان رساندید و میتوانید به درس بعدی بروید.