জাজানো মডেলএডমিনে ফরেনকেয়ের ক্ষেত্রগুলির বৈশিষ্ট্যগুলি প্রদর্শন করতে "list_display" করতে পারেন?


296

আমার একটি Personমডেল রয়েছে যার একটি বিদেশী কী সম্পর্ক Bookরয়েছে যার সাথে বেশ কয়েকটি ক্ষেত্র রয়েছে তবে আমি সবচেয়ে বেশি উদ্বিগ্ন author(একটি স্ট্যান্ডার্ড চারফিল্ড)।

এটির সাথে আমার PersonAdminমডেলটিতে, আমি এটি book.authorব্যবহার করে প্রদর্শন করতে চাই list_display:

class PersonAdmin(admin.ModelAdmin):
    list_display = ['book.author',]

আমি এটি করার জন্য সুস্পষ্ট সমস্ত পদ্ধতি ব্যবহার করে দেখেছি, তবে কিছুই কাজ করছে বলে মনে হচ্ছে না।

কোন পরামর্শ?

উত্তর:


472

অন্য বিকল্প হিসাবে, আপনি চেহারা আপ করতে পারেন:

class UserAdmin(admin.ModelAdmin):
    list_display = (..., 'get_author')

    def get_author(self, obj):
        return obj.book.author
    get_author.short_description = 'Author'
    get_author.admin_order_field = 'book__author'

উভয়ই হওয়া উচিত নয় get_author, যেহেতু আপনি যে স্ট্রিংটি ফিরে আসছেন তা (এবং সংক্ষিপ্ত বিবরণ) আসলে উল্লেখ করা উচিত? বা স্ট্রিং ফর্ম্যাট যুক্তি এ পরিবর্তন obj.book.reviews?
কার্ল জি

1
@ আনাতোলি আরকিপোভ, একটি উপায় আছে (টের উত্তরের ভিত্তিতে ) আমি ইতিমধ্যে এই উত্তরে কোড আপডেট করেছি।
ডেনিলসন সা মিয়া

আপনি কেন কেবল author = ForeignKey(Author)বইয়ের মডেলটিতে থাকতে পারবেন না , এবং তারপর list_display = ('author')?
ওরফে 5১

3
এটি অ্যাডমিনে প্রদর্শিত প্রতিটি সারিতে একটি ক্যোয়ারির কারণ :(
মার্শেল

1
@ মার্কসেল এটাই select_relatedযা করার জন্য। get_queryset()এর UserAdminওভাররাইট করতে হবে।
ইন্টারডিস্ট

142

উপরের সমস্ত দুর্দান্ত উত্তর থাকা সত্ত্বেও এবং আমার জ্যাঙ্গোতে নতুন হওয়ার কারণে, আমি তখনও আটকে ছিলাম। এখানে খুব নবাগত দৃষ্টিভঙ্গি থেকে আমার ব্যাখ্যা।

models.py

class Author(models.Model):
    name = models.CharField(max_length=255)

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=255)

অ্যাডমিনি.পি (ভুল উপায়) - আপনি মনে করেন যে এটি 'মডেল__ফিল্ড' রেফারেন্স ব্যবহার করে কার্যকর হবে, তবে তা হয় না

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'author__name', ]

admin.site.register(Book, BookAdmin)

অ্যাডমিনি.পি (সঠিক উপায়) - আপনি কীভাবে বিদেশি কী নাম জ্যাঙ্গো পথে উল্লেখ করেন

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'get_name', ]

    def get_name(self, obj):
        return obj.author.name
    get_name.admin_order_field  = 'author'  #Allows column order sorting
    get_name.short_description = 'Author Name'  #Renames column head

    #Filtering on side - for some reason, this works
    #list_filter = ['title', 'author__name']

admin.site.register(Book, BookAdmin)

অতিরিক্ত রেফারেন্সের জন্য, জাজানো মডেল লিঙ্কটি এখানে দেখুন


3
অর্ডার ক্ষেত্রের জন্য এটি = 'লেখক নাম' হওয়া উচিত নয়?
ইয়ুন্তি

2
এটি নিখুঁতভাবে কাজ করে তবে আমি কেন অনিশ্চিত। objহয় BookAdmin?
স্টিভেন চার্চ

কি দারুন. এটি খুঁজে পেতে আমাকে ওয়েবে এক ঘন্টা সময় নিয়েছে। এটি
জাজানো

67

বাকিদের মতো, আমি কলযোগ্যদের সাথেও গিয়েছিলাম। তবে তাদের একটি খারাপ দিক রয়েছে: ডিফল্টরূপে, আপনি সেগুলি অর্ডার করতে পারবেন না। ভাগ্যক্রমে, এর জন্য একটি সমাধান রয়েছে:

জ্যাঙ্গো> = 1.8

def author(self, obj):
    return obj.book.author
author.admin_order_field  = 'book__author'

জ্যাঙ্গো <1.8

def author(self):
    return self.book.author
author.admin_order_field  = 'book__author'

পদ্ধতির স্বাক্ষর হওয়া উচিতdef author(self, obj):
শেট

ফিরে যখন আমি মন্তব্য করলাম এটি ক্ষেত্রে হয়নি তবে এটি প্রদর্শিত হয় যে সংস্করণ 1.8 থেকে পদ্ধতিটি বস্তুটির কাছে চলে যায়। আমি আমার উত্তর আপডেট করেছি।
আরজেন

46

দয়া করে নোট করুন যে get_authorফাংশনটি যুক্ত করা অ্যাডমিনের তালিকা_পরিচালনকে ধীর করবে কারণ প্রতিটি ব্যক্তিকে দেখানো একটি এসকিউএল কোয়েরি তৈরি করবে make

এড়াতে, আপনাকে get_querysetপার্সোনএডমিনে পদ্ধতিটি পরিবর্তন করতে হবে , উদাহরণস্বরূপ:

def get_queryset(self, request):
    return super(PersonAdmin,self).get_queryset(request).select_related('book')

পূর্বে: 73৩.০২ এমএসে qu৩ টি প্রশ্ন (অ্যাডমিনে uplic 67 টি সদৃশ ক্যোয়ারী)

এর পরে: 10.81 মিমিগুলিতে 6 টি কোয়েরি


3
এটি সত্যই গুরুত্বপূর্ণ এবং সর্বদা প্রয়োগ করা উচিত
xleon

এটি সত্যই গুরুত্বপূর্ণ। বিকল্পভাবে, যদি কেউ এই __str__পথে যেতে হয় তবে কেবল বিদেশিটিকে যুক্ত করুন list_displayএবংlist_select_related
স্ক্র্যাচ'এন'পুর

22

ডকুমেন্টেশন অনুসারে, আপনি কেবলমাত্র __unicode__একটি বিদেশি কি উপস্থাপন করতে পারেন :

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#list-display

অদ্ভুত বলে মনে হচ্ছে এটি 'book__author'স্টাইল ফর্ম্যাটটিকে সমর্থন করে না যা ডিবি এপিআইয়ের অন্য যে কোনও জায়গায় ব্যবহৃত হয়।

দেখা যাচ্ছে এই বৈশিষ্ট্যের জন্য একটি টিকিট রয়েছে , যা উইন ফিক্স হিসাবে চিহ্নিত করা হয়েছে।


11
@ মেরমুজ আসলেই? এটি টিকিটটি wontfix হিসাবে সেট থাকবে বলে মনে হচ্ছে। এটি কাজ করে বলে মনে হচ্ছে না (জাজানো 1.3)
ডেভ

1.11 এখনও বিদ্যমান নেই। এক ডজন বছর ধরে জ্যাঙ্গো করা হয়েছে এবং আমি
অ্যারন ম্যাকমিলিন

12

আমি মাত্র একটি স্নিপেট পোস্ট করেছি যা প্রশাসক করে তোলে। মোডেলএডমিন '__' সিনট্যাক্স সমর্থন করে:

http://djangosnippets.org/snippets/2887/

সুতরাং আপনি এটি করতে পারেন:

class PersonAdmin(RelatedFieldAdmin):
    list_display = ['book__author',]

এটি মূলত অন্যান্য জবাবগুলিতে বর্ণিত একই জিনিসটি করছে তবে এটি স্বয়ংক্রিয়ভাবে (1) সেটিংস অ্যাডমিন_আর্ডারফিল্ড (2) সংক্ষিপ্ত বিবরণ স্থাপন এবং (3) প্রতিটি সারির জন্য একটি ডাটাবেস হিট এড়াতে ক্যোয়ারসেটটি সংশোধন করে।


আমি এই ধারণাটি অনেক পছন্দ করি, তবে সাম্প্রতিক জ্যাঙ্গো ভেরিয়ানের সাথে এটি আর কাজ করবে বলে মনে হয় না:AttributeError: type object 'BaseModel' has no attribute '__metaclass__'
ভিনসেন্ট ভ্যান

10

কল কল ব্যবহার করে আপনি তালিকার প্রদর্শনে যা খুশি তা প্রদর্শন করতে পারেন। এটি দেখতে এটি দেখতে হবে:

Def book_author (অবজেক্ট):
  রিটার্ন অবজেক্ট.বুক

ক্লাস পার্সনএডমিন (অ্যাডমিন.মোডেলএডমিন):
  list_display = [book_author,]

এটি পরিস্থিতিগুলির জন্য দুর্দান্ত, যেখানে প্রচুর বিভিন্ন মডেল প্রায়শই একই বৈশিষ্ট্যকে কল করে; এটি 1.3+ এ সমর্থিত?
কাগলি-সান

3
এটি নিয়ে সমস্যাটি শেষ পর্যন্ত সম্পন্ন এসকিউএল কোয়েরিগুলির পরিমাণ। তালিকার প্রতিটি বস্তুর জন্য এটি একটি ক্যোয়ারী তৈরি করবে। এই কারণেই 'ফিল্ড__অ্যাট্রিবিউট' খুব সহজ হবে, কারণ অবশ্যই জ্যাঙ্গো কেবল এটি একটি এসকিউএল কোয়েরিতে বিস্তৃত হবে। অদ্ভুত যে ইতিমধ্যে এটির কোনও সমর্থন নেই।
emyller

7

এটি ইতিমধ্যে স্বীকৃত, তবে যদি অন্য কোনও ডামি বাইরে থাকে (আমার মতো) যা অবিলম্বে এটি বর্তমানে গৃহীত উত্তর থেকে তা না পেয়ে থাকে , তবে এখানে আরও কিছু বিশদ দেওয়া হল।

মডেল শ্রেণীর প্রয়োজন অনুসারে রেফারেন্সের মধ্যে ForeignKeyএকটি __unicode__পদ্ধতি থাকা দরকার , এখানে এখানে:

class Category(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

এটি আমার পক্ষে পার্থক্য তৈরি করেছে এবং উপরের দৃশ্যে প্রয়োগ করা উচিত। এটি জাজানো 1.0.0 এ কাজ করে।


4
অজগর 3 এ হবে def __str__(self):
মার্টারলাক

5

আপনার যদি প্রচুর পরিমাণের বৈশিষ্ট্যযুক্ত ক্ষেত্রগুলি ব্যবহার করতে হয় list_displayএবং প্রতিটিটির জন্য একটি ফাংশন (এবং এটির বৈশিষ্ট্যগুলি) তৈরি করতে না চান, তবে একটি ময়লা কিন্তু সহজ সমাধান ModelAdminতাত্ক্ষণিক __getattr__পদ্ধতিটিকে ওভাররাইড করে এবং ফ্লাইতে কলগুলি তৈরি করে:

class DynamicLookupMixin(object):
    '''
    a mixin to add dynamic callable attributes like 'book__author' which
    return a function that return the instance.book.author value
    '''

    def __getattr__(self, attr):
        if ('__' in attr
            and not attr.startswith('_')
            and not attr.endswith('_boolean')
            and not attr.endswith('_short_description')):

            def dyn_lookup(instance):
                # traverse all __ lookups
                return reduce(lambda parent, child: getattr(parent, child),
                              attr.split('__'),
                              instance)

            # get admin_order_field, boolean and short_description
            dyn_lookup.admin_order_field = attr
            dyn_lookup.boolean = getattr(self, '{}_boolean'.format(attr), False)
            dyn_lookup.short_description = getattr(
                self, '{}_short_description'.format(attr),
                attr.replace('_', ' ').capitalize())

            return dyn_lookup

        # not dynamic lookup, default behaviour
        return self.__getattribute__(attr)


# use examples    

@admin.register(models.Person)
class PersonAdmin(admin.ModelAdmin, DynamicLookupMixin):
    list_display = ['book__author', 'book__publisher__name',
                    'book__publisher__country']

    # custom short description
    book__publisher__country_short_description = 'Publisher Country'


@admin.register(models.Product)
class ProductAdmin(admin.ModelAdmin, DynamicLookupMixin):
    list_display = ('name', 'category__is_new')

    # to show as boolean field
    category__is_new_boolean = True

এখানে সংক্ষেপ হিসাবে

Callable বিশেষ বৈশিষ্ট্য পছন্দ booleanএবং short_descriptionহিসাবে সংজ্ঞায়িত করা আবশ্যক ModelAdminবৈশিষ্ট্যাবলী যেমন book__author_verbose_name = 'Author name'এবং category__is_new_boolean = True

কলযোগ্য admin_order_fieldবৈশিষ্ট্য স্বয়ংক্রিয়ভাবে সংজ্ঞায়িত করা হয়।

জ্যাঙ্গো অ্যাডিশনাল কোয়েরি এড়াতে আপনার তালিকা_সিলিট_ সম্পর্কিত সম্পর্কিত বৈশিষ্ট্যটি ব্যবহার করতে ভুলবেন না ModelAdmin


1
এটি কেবল একটি জ্যাঙ্গো ২.২ ইনস্টল দিয়ে চেষ্টা করে দেখানো হয়েছে এবং এটি আমার পক্ষে দুর্দান্ত কাজ করেছে অন্য কারণগুলি যে কোনও কারণেই হয়নি। মনে রাখবেন যে আজকাল আপনাকে ফান্টুলগুলি বা অন্য কোথাও থেকে আমদানি করতে হবে ...
পল ব্র্যাকিন

5

পিআইপিআইতে খুব সহজেই ব্যবহারযোগ্য প্যাকেজ পাওয়া যায় যা হ্যান্ডেল করে: জ্যাঙ্গো-সম্পর্কিত-প্রশাসক । আপনি গিটহাবে কোডও দেখতে পাচ্ছেন

এটি ব্যবহার করে, আপনি যা অর্জন করতে চান তার মতোই সহজ:

class PersonAdmin(RelatedFieldAdmin):
    list_display = ['book__author',]

উভয় লিঙ্কে ইনস্টলেশন এবং ব্যবহারের সম্পূর্ণ বিবরণ রয়েছে যাতে তারা পরিবর্তিত হলে আমি এগুলিকে এখানে এখানে আটকাব না।

শুধু একটি সাইড নোট হিসাবে, যদি আপনি ইতিমধ্যে ছাড়া অন্য কিছু ব্যবহার করছেন model.Admin(যেমন আমি ব্যবহার করছিলেন SimpleHistoryAdminপরিবর্তে), আপনি এটা করতে পারেন: class MyAdmin(SimpleHistoryAdmin, RelatedFieldAdmin)


getter_for_related_field ১.৯-এ কাজ করে না তাই কাস্টমাইজ করা পছন্দ করেন তাদের কাছে এটি সেরা পছন্দ নয় বলে মনে হয়।
গ্রিমেল 14

4

আপনি যদি ইনলাইনে চেষ্টা করে থাকেন তবে আপনি সফল হবেন না যদি না:

আপনার ইনলাইন:

class AddInline(admin.TabularInline):
    readonly_fields = ['localname',]
    model = MyModel
    fields = ('localname',)

আপনার মডেলটিতে (মাইমোডেল):

class MyModel(models.Model):
    localization = models.ForeignKey(Localizations)

    def localname(self):
        return self.localization.name

-1

অ্যালেক্স্রোবিন্সের উত্তরটি আমার পক্ষে কাজ করেছিল, কেবলমাত্র প্রথম দুটি লাইন মডেলটিতে থাকা উচিত (সম্ভবত এটি অনুমান করা হয়েছিল?) এবং স্ব স্ব উল্লেখ করতে হবে:

def book_author(self):
  return self.book.author

তারপরে অ্যাডমিন অংশটি দুর্দান্তভাবে কাজ করে।


-5

আমি এটি পছন্দ করি:

class CoolAdmin(admin.ModelAdmin):
    list_display = ('pk', 'submodel__field')

    @staticmethod
    def submodel__field(obj):
        return obj.submodel.field
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.