1

我有一个带有用户的 Django 应用程序。我有一个名为“Course”的模型,带有一个名为“teacher”的外键,用于 Django 提供的默认用户模型:

class Course(models.Model):
    ...
    teacher = models.ForeignKey(User, related_name='courses_taught')

当我创建一个模型表单来编辑个别课程的信息时,教师字段的可能用户出现在这个用户名的长选择菜单中。

在此处输入图像描述

这些用户是按 ID 排序的,这对我来说用处不大。我怎样才能

  1. 按姓氏对这些用户排序?
  2. 将 User 类的字符串表示形式更改为“Firstname Lastname (username)”而不是“username”?
4

3 回答 3

0

抽象的

如果您只与管理员打交道,最好不要修改User模型本身,因为子类User化可能会很痛苦(特别是当/如果其他开发人员要处理您的项目时),但使用管理员的自定义选项。

解决方案

要在管理员中解决您的问题,您可以使用ModelAdmin选项raw_id_fields.

这将<select>用一个小部件替换输入,您可以单击该小部件以重定向到您的User管理员并从中选择您的用户。

从那里,自定义您的User管理员是微不足道的,以便它:

  • 按相关顺序显示您的用户 ( ModelAdmin.ordering)
  • 显示您感兴趣的字段 ( ModelAdmin.list_display)

请记住,当您注册User管理员时,您需要使用:

admin.site.unregister(User) #This!
admin.site.register(User, MyCustomUserAdmin)

替代解决方案

或者,您始终可以使用ModelAdmin.formfield_overrides,它更强大但更复杂。

参考

您应该查看Django 文档以获取有关如何使用这些属性的详细信息。

于 2012-06-02T20:09:06.873 回答
0

You could achieve this by customizing form field, here the forms.ModelChoiceField

 class CustomizedModelChoiceField(forms.ModelChoiceField):
     def __init__(self, *args, **kwargs):
         # change default ordering
         super(CustomizedModelChoiceField, self).__init__(*args, **kwargs)
         self.queryset = self.queryset.order_by('last_name')

     def label_from_instance(self, obj):
         # change representation per item
         return u'{obj.first_name} {obj.last_name} ({obj.username})'.format(obj=obj)

Then use it in your form to replace default ModelChoiceField.

In Django Admin, it looks like

class CourseAdmin(admin.ModelAdmin):    
     def formfield_for_dbfield(self, db_field, **kwargs):
         if db_field.name == 'teacher':
             kwargs['form_class'] = CustomizedModelChoiceField
         return super(CourseAdmin, self).formfield_for_dbfield(db_field, **kwargs)
于 2012-06-03T07:01:26.313 回答
0

首先,顺序。您可以使用嵌套Meta定义模型的默认顺序。检查订购部分。

其次,代表性。您必须为模型定义__str__()/__unicode__()方法。它们应该返回一个代表对象的字符串。您可以在文档中查看示例。但是,由于User是来自外部模块的模型,因此可能很难以这种方式进行。

您可能可以:

  • User在应用程序初始化期间猴子修补模型元类或
  • 子类化User模型,添加Meta到子类并使用它代替UserOR
  • 编写一个使用对象属性而不是调用的自定义字段/表单模板str()

这一切都取决于当前的情况

于 2012-06-02T16:53:05.170 回答