Upgrade to Pro — share decks privately, control downloads, hide ads and more …

날로_먹는_Django_Admin_활용.pdf

Avatar for Kay Cha Kay Cha
November 06, 2017
33

 날로_먹는_Django_Admin_활용.pdf

Avatar for Kay Cha

Kay Cha

November 06, 2017
Tweet

Transcript

  1. ߊ಴੗ࣗѐ • 차경묵 (한날) • 프리랜서 개발자 • 날로 먹는

    Django 웹 프로그래밍 (2008) • 날로 먹는 Django 웹 프레임워크 (2014) • http://blog.hannal.com
  2. ProfileNPEFM class Profile(models.Model): registration_routes = ( ('direct', _('૒੽ ߑޙ оੑ'),

    ), ('guestbook', _('ѱझ౟࠘'), ), ('cocoa', _('௏௏ইస'), ), ('goggle', _('ҊӖ'), ), ('navar', _('ա߄'), ), ) user = models.OneToOneField(settings.AUTH_USER_MODEL) registration_route = models.CharField(_('оੑ ҃۽'), max_length=40, choices=registration_routes, default='direct')
  3. ProductNPEFM class Product(models.Model): statuses = ( ('active', _('੿࢚'), ), ('sold_out',

    _('ಿ੺'), ), ('obsolete', _('ױઙ'), ), ('deactive', _('࠺ഝࢿച'), ), ) categories = ( ('decoration', _('੢ध'), ), ('pan', _('ಃ'), ), ('roll', _('܀'), ), ) category = models.CharField(_('࢚ಿ тې'), max_length=20, choices=categories) name = models.CharField(_('࢚ಿݺ'), max_length=100) content = models.TextField(_('ࢸݺ')) regular_price = models.PositiveIntegerField(_('੿о')) selling_price = models.PositiveIntegerField(_('౸ݒо')) status = models.CharField(_('࢚క'), max_length=20, choices=statuses) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True)
  4. ProductImageNPEFM class ProductImage(models.Model): product = models.ForeignKey(Product) content = models.ImageField() created_at

    = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True)
  5. OrderNPEFM from uuid import uuid4 class Order(models.Model): progresses = (

    ('requested', _('઱ޙ ਃ୒'), ), ('checkout_payment', _('Ѿઁ ഛੋ ઺'), ), ('paid', _('Ѿઁ ৮ܐ'), ), ('failed_payment', _('Ѿઁ पಁ'), ), ('prepared_product', _('࢚ಿ ળ࠺'), ), ('prepared_delivery', _('୹Ҋ ળ࠺'), ), ('ongoing_delivery', _('ߓ࣠ ઺'), ), ('done', _('Ѣې ৮ܐ'), ), ) sn = models.UUIDField(_('ੌ۲ߣഐ'), unique=True, editable=False, default=uuid4) user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True) items = models.ManyToManyField(Product) product_cost = models.IntegerField(_('઱ޙ ୨ঘ')) progress = models.CharField(_('૓೯࢚క'), max_length=20, choices=progresses, default='requested') comment = models.TextField(_('ӝఋ ਃ୒ࢎ೦'), null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True)
  6. ݾ۾ചݶী୹۱ղਊ૑੿ ↟ݽ؛߹"ENJOੋఠಕ੉झٜܳ݅"ENJO௿ېझٜܳ݅Ҋ%KBOHP"ENJOী١ ۾ ↟list_displayݯߡ߸ࣻݾ۾ചݶী಴दೡݽ؛੉աݽ؛੄"ENJOࣘࢿ BUUSJCVUFT  @admin.register(models.Product) class ProductAdmin(admin.ModelAdmin): list_display

    = ( 'pk', 'name', 'category', 'regular_price', 'selling_price', 'status', 'created_at', 'updated_at', ) ژח admin.site.register(models.Product, ProductAdmin) ੢ध੗ܳॳחߑߨҗ૒੽ ݽ؛җ"ENJO௿ېझܳ૟ ૑য١۾ೞחߑߨ਷زੌೠ ز੘ੑפ׮
  7. ݽ؛೙٘ীহחղਊਸݾ۾ী಴दೞӝ ↟"ENJO੄ࣘࢿ ઱۽ݫࢲ٘ ૑੿ ↟೧׼ݫࢲ٘ীAshort_descriptionAחৌ੉ܴਵ۽ࢎਊؽ from django.utils.translation import ugettext as

    _ from django.utils.safestring import mark_safe @admin.register(models.Product) class ProductAdmin(admin.ModelAdmin): list_display = ( 'get_title_image', 'pk', 'name', 'category', 'regular_price', 'selling_price', 'status', 'created_at', 'updated_at', ) list_display_links = ( 'get_title_image', 'pk', 'name', 'category', 'regular_price', 'selling_price', 'status', 'created_at', 'updated_at', ) # ࢤۚ def get_title_image(self, obj): image = obj.productimage_set.order_by('pk').first() if not image: return '' return mark_safe(f'<img src="{image.content.url}" style="width: 50px;">') get_title_image.short_description = _('ઁಿ ੉޷૑')
  8. %KBOHP6TFS"ENJOࣻ੿ ↟%KBOHPղ੢6TFSݽ؛ਸࢎਊೞח҃਋ %KBOHP"ENJOী١۾ػUser ݽ؛ਸ١۾೧ઁ೧ঠೣ ↟Userݽ؛ী؀ೠ"ENJOਸ١۾೧ઁೞחѱইפۄݽ؛ਸ೧ઁೞחѪী ઱੄ from django.contrib.auth.models import User

    admin.site.unregister(User) ژח from django.contrib.auth import get_user_model user_model = get_user_model() admin.site.unregister(user_model) ੉҃਋ח%KBOHPীࢲઁҕೞח Userݽ؛ਸ١۾೧ઁೞחѪ੉ ޲۽ݺഛೞѱ؀࢚ݽ؛ੋUser ܳ߄۽JNQPSUೞחѱա਺
  9. %KBOHP6TFS"ENJOࣻ੿ ↟Userݽ؛ী؀ೠ"ENJO௿ېझܳ࢜۽ٜ݅যبغҊ  ↟%KBOHPীղ੢ػUserAdmin௿ېझ࢚ܳࣘ߉ইࣻ੿೧بغҊ from django.contrib.auth.admin import UserAdmin @admin.register(user_model) class

    CustomUserAdmin(UserAdmin): list_display = UserAdmin.list_display + ('get_registration_route', ) def get_registration_route(self, obj): try: return obj.profile.get_registration_route_display() except models.Profile.DoesNotExist: return '?' get_registration_route.short_description = _('оੑ҃۽')
  10. оੑ҃۽۽୶۰ղӝ ↟.PEFMNBOBHFS۽ؘ੉ఠఐ࢝दࢎਊೞחݽ؛ҙ҅ఐ࢝ޙߨࢎਊ оמ • User.objects.filter(profile__registration_route='direct') @admin.register(user_model) class CustomUserAdmin(UserAdmin): list_display =

    UserAdmin.list_display + ('get_registration_route', ) list_filter = UserAdmin.list_filter + ('profile__registration_route', ) def get_registration_route(self, obj): try: return obj.profile.get_registration_route_display() except models.Profile.DoesNotExist: return '?' get_registration_route.short_description = _('оੑ҃۽')
  11. ઱ޙപࣻ೙ఠ ↟admin.SimpleListFilter௿ېझ࢚ܳࣘ߉ই૒੽-JTUGJMUFSܳ੘ࢿ೧ঠೞח࢚ട ↟lookups()೙ఠ6*ী಴दೡఐ࢝чҗఐ࢝಴दݺਸtuple۽ޘযࢲ߈ജ ↟queryset()೙ఠী؀೧ࢤࢿೡQuerySetё୓ܳ߈ജ೙ఠחࢲ۽׮ܲ೙ఠ৬઺୏غয૕ ੄૘೤ਸٜ݅ࣻ੓ਵ޲۽߈٘दQuerySetё୓ܳ߈ജ೧ঠೣ from django.db.models import Count, Case,

    When, IntegerField class UserOrderCountFilter(admin.SimpleListFilter): title = _('ҳݒപࣻ') parameter_name = 'order_count' def lookups(self, request, model_admin): return ( ('exact-0', _('হ਺'), ), ('exact-1', _('1ഥ'), ), ('exact-2', _('2ഥ'), ), ('exact-3', _('3ഥ'), ), ('gt-3', _('3ഥ ୡҗ'), ), ) # ׮਺ ੢ীࢲ ҅ࣘ
  12. ઱ޙപࣻ೙ఠ # ੉যࢲ def queryset(self, request, queryset): value = self.value()

    if not value: return queryset try: lookup_keyword, count = value.split('-') count = int(count) if count == 0: users = models.Order.objects \ .filter(progress='done') \ .values_list('user__id') return queryset.exclude(pk__in=users) else: return queryset \ .annotate(cnt=Count(Case( When(order__progress='done', then=0), output_field=IntegerField() ))).filter(** {f'cnt__{lookup_keyword}': count}) except Exception: return queryset.none()
  13. ־੸઱ޙ୨ঘ೙ఠ ↟઱ޙപࣻ೙ఠ৬Ѣ੄زੌ from django.db.models import Sum class SumOrderCostFilter(admin.SimpleListFilter): title =

    _('־੸ ҳݒ୨ঘ') parameter_name = 'order_cost' def lookups(self, request, model_admin): return ( ('lt-50000', _('5݅ਗ ޷݅'), ), ('gte-50000--lt-100000', _('5݅ਗ ੉࢚ 10݅ਗ ޷݅'), ), ('gte-100000--lt-200000', _('10݅ਗ ੉࢚ 20݅ਗ ޷݅'), ), ('gte-200000--lt-500000', _('20݅ਗ ੉࢚ 50݅ਗ ޷݅'), ), ('gte-500000', _('50݅ਗ ੉࢚'), ), )
  14. ־੸઱ޙ୨ঘ೙ఠ # ੉যࢲ def queryset(self, request, queryset): value = self.value()

    if not value: return queryset try: l1, l2 = value.split('--') except ValueError: l1, l2 = value, None lookups = {} for l in (l1, l2): if not l: continue try: lookup_keyword, amount = l.split('-') lookups[f'cost__{lookup_keyword}'] = int(amount) except ValueError: continue # ׮਺ ੢ী ҅ࣘ
  15. ־੸઱ޙ୨ঘ೙ఠ def queryset(self, request, queryset): # ࢤۚ # ੉যࢲ if

    not lookups: return queryset.none() try: return queryset.filter(order__progress='done') \ .annotate(cost=Sum('order__product_cost')) \ .filter(**lookups) except Exception: return queryset.none()
  16. $VTUPN"ENJO"DUJPO ↟"ENJO௿ېझ੄actionsࣘࢿীഐ୹оמೠё୓ܳ١۾ ↟ݾ۾ചݶীࢎਊ੗о୶оೠ"DUJPO੉"DUJPO%SPQEPXO6*ী୶оؽ ↟ੋ੗۽ֈযয়חquerysetё୓ূ੉ਊ੗оࢶఖೠ೦ݾ੉׸ѹ੓਺ from django.contrib import messages def change_progress_to_ongoing_delivery(modeladmin,

    request, queryset): queryset.update(progress='ongoing_delivery') messages.success(request, _('ߓ࣠ ࢚క۽ ߸҃೮णפ׮.')) change_progress_to_ongoing_delivery.short_description = _('ߓ࣠ ࢚క۽ ߸҃') @admin.register(models.Order) class OrderAdmin(admin.ModelAdmin): # ࢤۚ actions = (change_progress_to_ongoing_delivery, )
  17. ࢚ࣁࠁӝಕ੉૑ীࢲౠ੿੗ܐী݅ز੘ೞח"DUJPO୶оߑߨ from django_object_actions import DjangoObjectActions @admin.register(user_model) class CustomUserAdmin(DjangoObjectActions, UserAdmin): #

    ࢤۚ change_actions = ('make_user_happy', ) def make_user_happy(self, request, obj): messages.info(request, f'{obj}שਸ ೯ࠂೞѱ ೮णפ׮.') # do something make_user_happy.label = _('੉ਊ੗ ೯ࠂೞѱ ೞӝ') make_user_happy.short_description = _('੉ਊ੗ ೯ࠂೞѱ ೞӝ')