مجتبی کریمی
مجتبی کریمی
خواندن ۳ دقیقه·۵ سال پیش

آموزش ساخت List Action در محیط ادمین جنگو

هدف از ایجاد List Action در ادمین جنگو انجام عملیات روی آبجکت های یک مدل به صورت انبوه است. تمامی مدل ها در محیط ادمین جنگو با یک Action پیشفرض “حذف <نام مدل> انتخاب شده” همراه هستند. در این آموزش من شما را در مراحل ساخت List Action راهنمایی می کنم.

ایجاد تابع Action

هر Action در لیست آبجکت ها یک تابع معمولی پایتون است که 3 پارامتر را به عنوان ورودی دریافت می کند:

  1. modeladmin فعلی
  2. یک رکوئست (مثل توابعی که برای ویو می نویسیم)
  3. Queryset که یک لیست از آبجکت هایی است که می خواهیم تغییرات را بر روی آن ها اعمال کنیم

این تابع های Action در داخل فایل admin.py  اپ جنگو ما قرار میگیرند ولی اگر واقعا در حال زیاد شدن بودند، میتوانید اونها را خارج از admin.py هم تعریف کنید.

در ادامه نمونه کد پایه یک تابع Action را مشاهده می کنید:

def my_admin_action(modeladmin, request, queryset): # do something with the queryset my_admin_action.short_description = 'My admin action'

به عنوان یک نمونه ساده این مدل را در نظر بگیرید:

models.py

from django.db import models class Book(models.Model): HARDCOVER = 1 PAPERBACK = 2 EBOOK = 3 BOOK_TYPES = ( (HARDCOVER, 'Hardcover'), (PAPERBACK, 'Paperback'), (EBOOK, 'E-book'), ) title = models.CharField(max_length=50) publication_date = models.DateField(null=True) author = models.CharField(max_length=30, blank=True) price = models.DecimalField(max_digits=5, decimal_places=2) pages = models.IntegerField(blank=True, null=True) book_type = models.PositiveSmallIntegerField(choices=BOOK_TYPES) class Meta: verbose_name = 'book' verbose_name_plural = 'books'

admin.py

from django.contrib import admin from .models import Book class BookAdmin(admin.ModelAdmin): list_display = ['title', 'publication_date', 'author', 'price', 'book_type'] admin.site.register(Book, BookAdmin)

حالا می خواهیم یک List Action بسازیم تا 10 درصد تخفیف روی کتاب های انتخاب شده اعمال کند. این کار به همین سادگی خواهد بود:

admin.py

import decimal from django.contrib import admin from .models import Book def apply_discount(modeladmin, request, queryset): for book in queryset: book.price = book.price * decimal.Decimal('0.9') book.save() apply_discount.short_description = 'Apply 10%% discount' class BookAdmin(admin.ModelAdmin): list_display = ['title', 'publication_date', 'author', 'price', 'book_type'] actions = [apply_discount, ] # <-- Add the list action function here admin.site.register(Book, BookAdmin)

فراموش نکنید که نام تابعی را که ساختید، در لیست actions اضافه کنید. نتیجه چنین چیزی خواهد بود:

نکته: شما می توانید تابع apply_discount را با استفاده از اصطلاح ()F در جنگو بهینه تر کنید:

from django.db.models import F def apply_discount(modeladmin, request, queryset): queryset.update(price=F('price') * decimal.Decimal('0.9'))

نمونه خروجی CSV

همچنین شما می توانید از List Action استفاده کنید تا به شما یک HttpResponse برگشت دهد. یک نمونه ساده خروجی به CSV:

admin.py

import decimal, csv from django.contrib import admin from django.http import HttpResponse from django.db.models import F from .models import Book def apply_discount(modeladmin, request, queryset): queryset.update(price=F('price') * decimal.Decimal('0.9')) apply_discount.short_description = 'Apply 10%% discount' def export_books(modeladmin, request, queryset): response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=&quotbooks.csv&quot' writer = csv.writer(response) writer.writerow(['Title', 'Publication Date', 'Author', 'Price', 'Pages', 'Book Type']) books = queryset.values_list('title', 'publication_date', 'author', 'price', 'pages', 'book_type') for book in books: writer.writerow(book) return response export_books.short_description = 'Export to csv' class BookAdmin(admin.ModelAdmin): list_display = ['title', 'publication_date', 'author', 'price', 'book_type'] actions = [apply_discount, export_books, ] admin.site.register(Book, BookAdmin)

List Action به عنوان تابع کلاس Model Admin

یک روش جایگزین برای انجام این کار،  ایجاد تابع List Action به عنوان یک متد از کلاس ادمین است:

class BookAdmin(admin.ModelAdmin): list_display = ['title', 'publication_date', 'author', 'price', 'book_type'] actions = ['apply_discount', export_books] def apply_discount(self, request, queryset): queryset.update(price=F('price') * decimal.Decimal('0.9')) apply_discount.short_description = 'Apply 10%% discount'

نام متدی را که ساختید، در قالب یک رشته به لیست actions ارسال کنید و اولین آرگومان (کلمه کلیدی modeladmin) را به self تغییر نام دهید.

امیدوارم از این آموزش بهره ببرید!

منبع: simpleisbetterthancomplex

جنگوپایتونادمین جنگولیست اکشن
گیک علاقه‌مند به یادگیری و گسترش دانش
شاید از این پست‌ها خوشتان بیاید