سؤال

لدي تطبيق يستخدم Django UserProfile لتوسيع django المدمج User نموذج. يبدو قليلا مثل:

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    # Local Stuff
    image_url_s = models.CharField(max_length=128, blank=True)
    image_url_m = models.CharField(max_length=128, blank=True)

    # Admin
    class Admin: pass

لقد أضفت فئة جديدة إلى نموذجي:

class Team(models.Model):
    name = models.CharField(max_length=128)
    manager = models.ForeignKey(User, related_name='manager')
    members = models.ManyToManyField(User, blank=True)

وهي مسجلة في المشرف:

class TeamAdmin(admin.ModelAdmin):
    list_display = ('name', 'manager')

admin.site.register(Team, TeamAdmin)

Alas، في Edmin Inteface، عندما أذهب إلى تحديد مدير من المربع المنسدل، أو تعيين أعضاء الفريق عبر حقل متعدد المحدد، يتم طلبها من قبل معرف المستخدم رقمي. لحياة لي، لا أستطيع معرفة كيفية الحصول على هذه المرتبة.

لدي فئة مماثلة مع:

class Meta:
    ordering = ['name']

التي تعمل كبيرة! لكنني لا "أملك" User فئة، وعند محاولة هذه الخدعة في UserAdmin:

class Meta:
    ordering = ['username']

انا حصلت:

django.core.management.base.CommandError: One or more models did not validate: events.userprofile: "ordering" refers to "username", a field that doesn't exist.

user.username لا يعمل أيضا. يمكنني تحديد، مثل image_url_s إذا أردت أن . وبعد وبعد كيف يمكنني إخبار المشرف بفرز قوائم المستخدمين usernameب شكرًا!

هل كانت مفيدة؟

المحلول

طريقة واحدة هي تحديد نموذج مخصص للاستخدام لنموذج فريقك في المسؤول، وتجاوز manager حقل لاستخدام queryset مع الطلب الصحيح:

from django import forms

class TeamForm(forms.ModelForm):
    manager = forms.ModelChoiceField(queryset=User.objects.order_by('username'))

    class Meta:
        model = Team

class TeamAdmin(admin.ModelAdmin):
    list_display = ('name', 'manager')
    form = TeamForm

نصائح أخرى

هذه

class Meta:
    ordering = ['username']

يجب ان يكون

    ordering = ['user__username']

إذا كان في فئة مسؤول المستخدم الخاص بك. هذا سوف يتوقف الاستثناء، لكن لا أعتقد أنه يساعدك.

طلب طراز المستخدم كما تصف صعبة للغاية، ولكن انظر http://code.djangoproject.com/ticket/6089#comment:8. للحل.

قد يكون هذا خطيرا لسبب ما، ولكن يمكن القيام بذلك في سطر واحد في مشروعك models.py ملف:

User._meta.ordering=["username"]

بالنسبة لي، كان حل العمل الوحيد هو استخدام نموذج الوكيل. وبعد كما هو مذكور في الوثائق، يمكنك إنشاء نماذج وكيل خاصة حتى نماذج مدمجة وتخصيص أي شيء مثل النماذج العادية:

class OrderedUser(User):
    class Meta:
        proxy = True
        ordering = ["username"]
    def __str__(self):
        return '%s %s' % (self.first_name, self.last_name)

بعد ذلك، في نموذجك فقط تغيير المفتاح الأجنبي إلى:

user = models.OneToOneField(OrderedUser, unique=True)

أو حتى أكثر ملاءمة

user = models.OneToOneField(OrderedUser, unique = True, parent_link = True)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top