Как получить фактический идентификатор объекта на странице администратора Django (внутри formfield_for_foreignkey)? - PullRequest
6 голосов
/ 06 января 2011

Я уже решил проблему получения редактируемого идентификатора объекта с помощью этого кода:

class CompanyUserInline(admin.StackedInline):
    """
    Defines tabular rules for editing company users direct in company admin
    """
    model = CompanyUser

    def formfield_for_foreignkey(self, db_field, request, **kwargs):

        if db_field.name == "user":
            users = User.objects.filter( Q(is_superuser=False) )
            query = Q()
            for u in users:
                aux = CompanyUser.objects.filter(user=u)
                if aux.count() == 0:
                    query |= Q(pk=u.id)

            try:
                cpu = CompanyUser.objects.filter(company__id=int(request.path.split('/')[4]))
                for p in cpu:
                    query |= Q(pk=p.user.id)
            except:
                pass

            kwargs["queryset"] = User.objects.filter(query).order_by('username')

        return super(CompanyUserInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

Но int (request.path.split ('/') [4]]) действительно безобразно.Я хочу знать, как я могу получить идентификатор из Django AdminModel.Я уверен, что это где-то внутри, кто-нибудь знает?

Заранее спасибо!; D

Ответы [ 6 ]

9 голосов
/ 05 декабря 2014

После некоторого поиска мы смогли получить аргументы, которые передаются в представление администратора (после анализа в django urls.py администратора) и использовать его (self_pub_id) для захвата объекта:

class PublicationAdmin(admin.ModelAdmin):

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "authors":
            #this line below got the proper primary key for our object of interest
            self_pub_id = request.resolver_match.args[0]

            #then we did some stuff you don't care about
            pub = Publication.objects.get(id=self_pub_id)
            kwargs["queryset"] = pub.authors.all()
        return super(PublicationAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

Более элегантное решение - использовать рекомендацию принятых ответов и использовать функцию-член get_form ModelAdmin.Вот так:

class ProfileAdmin(admin.ModelAdmin):
    my_id_for_formfield = None
    def get_form(self, request, obj=None, **kwargs):
        if obj:
            self.my_id_for_formfield = obj.id
        return super(ProfileAdmin, self).get_form(request, obj, **kwargs)

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "person":
            kwargs["queryset"] = Person.objects.filter(profile=self.my_id_for_formfield)
        return super(ProfileAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
8 голосов
/ 06 января 2011

Насколько я знаю, невозможно получить доступ к текущему экземпляру через formfield_for_... -методы, потому что они будут вызываться только для одного экземпляра поля!логика, при которой вы можете получить доступ ко всему экземпляру / форме, будет get_form.Там же вы можете переписать набор запросов поля формы!

4 голосов
/ 16 июля 2016

Я заставил это работать, переписав change_view()

class CartAdmin(admin.ModelAdmin):

def change_view(self, request, object_id, form_url='', extra_context=None):
    self.object_id = object_id
    return self.changeform_view(request, object_id, form_url, extra_context)


def formfield_for_foreignkey(self, db_field, request, **kwargs):
    print self.object_id
    return super(CartAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

тогда вы можете позвонить self.object_id внутри formfield_for_foreignkey()

1 голос
/ 29 сентября 2018

Следующий фрагмент кода даст вам идентификатор объекта:

request.resolver_match.kwargs['object_id']

Пример использования: (Я фильтрую показанные номера телефонов, чтобы показать только номера телефонов клиентов)

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == 'preferred_contact_number':
        kwargs['queryset'] = CustomerPhone.objects.filter(customer__pk=request.resolver_match.kwargs['object_id'])
    return super().formfield_for_foreignkey(db_field, request, **kwargs)

PS: нашел его путем отладки и просмотра доступных переменных.

0 голосов
/ 23 октября 2015

Я заставил это работать, создав свойство () в model.py, которое возвращает идентификатор

models.py:

class MyModel(models.Model):
    myfield = models.CharField(max_length=75)
    ...
    def get_id(self):
        return str(self.id)
    getid = property(get_id)

admin.py:

from myapp.models import MyModel

class MyModelAdmin(admin.ModelAdmin):
    list_display = ['mylink',]
    def mylink(self, object):
        return '<a href="http://mywebsite/'+object.getid+'/">Edit</a>'
    mylink.allow_tags = True

admin.site.register(MyModel, MyModelAdmin)
0 голосов
/ 17 февраля 2013

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

cpu = CompanyUser.objects.filter(company__id=self.company_id)

или что вообще диктует структура вашей модели.

...