Django Admin Model при добавлении не может отобразить ссылку на связанное изменение - PullRequest
1 голос
/ 05 апреля 2019

С учетом следующих настроек администратора:

class BrokerLocationSetForm(forms.ModelForm):
    class Meta:
        model = BrokerLocationSet
        fields = ('broker', 'program', 'label', 'locations')
        widgets = {
            'locations': autocomplete.ModelSelect2Multiple(url='admin-autocomplete-location', forward=('broker','program')),
        }
class BrokerLocationSetAdmin(admin.ModelAdmin):
    model = BrokerLocationSet
    form = BrokerLocationSetForm
    list_display=['broker', 'program', 'label']
admin.site.register(BrokerLocationSet, BrokerLocationSetAdmin)

Когда я пытаюсь перейти, чтобы добавить представление в admin для BrokerLocationSetForm, возникает следующая ошибка:

raise NoReverseMatch(msg) NoReverseMatch: Reverse for 'program_program_change' with arguments '(u'__fk__',)' not found. 1 pattern(s) tried: [u'admin/program/program/(?P<program_pk>\\d+)/change/$']

Когда я отлаживаю в оболочке:

 reverse('admin:broker_broker_change', 'myapp.urls', args=(u'__fk__',))

выводит:

и '/ администратор / брокер / брокер / Ф.К. / изменение /'

но для:

reverse('admin:program_program_change', 'myapp.urls', args=(u'__fk__',))

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

reverse('admin:program_program_change', 'myapp.urls', args=(u'1',))

и '/ администратор / программы / программы / 1 / изменение /'

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

Как я могу исправить вышеуказанную ошибку, настроив модель или форму администратора. Я не хочу обновлять 'admin: program_program_change', но, вероятно, предоставлю альтернативный маршрут к тому же представлению! , Является ли это возможным ? пожалуйста посоветуйте!

1 Ответ

0 голосов
/ 08 апреля 2019

Я нашел решение, но не уверен, что это лучшее решение.Так как ProgramAdmin ожидает числовой параметр, а всплывающая ссылка от BrokerLocationSetAdmin ожидает маршрут со строковым параметром.Например,

reverse('admin:program_program_change', 'myapp.urls', args=(u'__fk__',))

Решение заключалось в том, чтобы внедрить другой маршрут администратора с тем же именем в модель ProgramAdmin путем переопределения метода get_urls следующим образом:

class ProgramAdmin(admin.ModelAdmin):
   ...
   ...
   def get_urls(self):
        from django.conf.urls import url
        from functools import update_wrapper

        def wrap(view):
            def wrapper(*args, **kwargs):
                return self.admin_site.admin_view(view)(*args, **kwargs)
            wrapper.model_admin = self
            return update_wrapper(wrapper, view)

        urls = super(ProgramAdmin, self).get_urls()
        info = self.model._meta.app_label, self.model._meta.model_name
        alt_urls=[
            url(r'^(?P<program_pk>\w+)/change/$', wrap(self.change_view), name='%s_%s_change' % info),
        ]
        return urls+alt_urls

Теперь у нас есть два маршрута сто же имя, но разные параметры пути, например:

/admin/program/program/<program_pk>/change/ django.contrib.admin.options.change_view    admin:program_program_change

admin / program / program / (? P \ d +) / change / $

/admin/program/program/<program_pk>/change/ django.contrib.admin.options.change_view    admin:program_program_change

admin / program / program / (? P \ w +) / change / $

В зависимости от контекста будет использоваться один из маршрутов.

...