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

?How to Build List Action in Django Admin

13 اردیبهشت 1400
featured-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="books.csv"'

    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 تغییر نام دهید.

امیدواریم از بحث ساخت List Action در ادمین جنگو استفاده کافی را برده باشید.


منبع: سایت Simple is Better Than Complex

نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.