DJANGO ADMIN: طلب الأمر تفشي العلاقات بين الأمرينويكي
-
16-09-2019 - |
سؤال
لدي تطبيق يستخدم 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)