Как сделать пользовательское отображение и автоматический выбор в поле множественного выбора администратора django? - PullRequest
1 голос
/ 23 апреля 2010

Я новичок в django, поэтому, пожалуйста, не стесняйтесь сказать мне, если я делаю это неправильно. Я пытаюсь создать систему заказов Django. Модель моего заказа:

class Order(models.Model):
    ordered_by = models.ForeignKey(User, limit_choices_to = {'groups__name': "Managers", 'is_active': 1})

в моем админе ЛЮБОЙ пользователь может ввести заказ, но order_by должен быть кем-то из группы "менеджеры" (это поведение, которое я хочу).

Теперь, если вошедший в систему пользователь оказался менеджером, я хочу, чтобы он автоматически заполнил поле тем, кто вошел в систему. Я достиг этого путем:

class OrderAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == "ordered_by":
        if request.user in User.objects.filter(groups__name='Managers', is_active=1):
            kwargs["initial"] = request.user.id
        kwargs["empty_label"] = "-------------"
        return db_field.formfield(**kwargs)
    return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

Это также работает, но администратор по умолчанию помещает имя пользователя в качестве дисплея для поля выбора. Было бы неплохо, чтобы в списке было настоящее имя пользователя. Я смог сделать это с этим:

class UserModelMultipleChoiceField(forms.ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.first_name + " " + obj.last_name
class OrderForm(forms.ModelForm):
    ordered_by = UserModelChoiceField(queryset=User.objects.all().filter(groups__name='Managers', is_active=1))

class OrderAdmin(admin.ModelAdmin):
    form = OrderForm

Моя проблема: я не могу с обоими из них. Если я добавлю функцию formfield_for_foreignkey и добавлю form = OrderForm, чтобы использовать мой пользовательский «UserModelChoiceField», он отобразит красивое имя, но не выберет вошедшего в систему пользователя. Я новичок в этом, но я предполагаю, что когда я использую UserModelChoiceField, он «стирает» информацию, переданную через formfield_for_foreignkey. Нужно ли как-то использовать функцию super () для передачи этой информации? или что-то совсем другое?

1 Ответ

0 голосов
/ 16 марта 2012

Полностью исключить подкласс ModelChoiceField / ModelMultipleChoiceField и отработать метод formfield_for_foreignkey. Аргумент request недоступен в подклассе, поэтому вы не можете получить текущего пользователя.

Затем используйте label_from_instance метод внутри formfield_for_foreignkey. Вы можете написать это самостоятельно, но надежный фрагмент Django доступен по адресу http://djangosnippets.org/snippets/1642/. Просто создайте подкласс класса из этого фрагмента. Вы можете поместить его в другой файл и импортировать его или просто написать над классом OrderAdmin как OrderAdmin(NiceUserModelAdmin).

Наконец, перепишите метод formfield_for_foreignkey, чтобы получить kwargs["initial"] = request.user.id вне оператора if. Я не думаю, что это необходимо, и у меня тоже были проблемы с этим.

# admin.py

from django.contrib import admin
from django.contrib.auth.models import User
from (...) import Order

class NiceUserModelAdmin(admin.ModelAdmin):
    # ...

class OrderAdmin(NiceUserModelAdmin):
    # ...
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        kwargs["initial"] = request.user.id
        if db_field.name == "ordered_by":
            kwargs["empty_label"] = "-------------"
            return db_field.formfield(**kwargs)
        return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
...