Есть ли лучший, более СУХОЙ способ создания повторяющихся наборов представлений и URL-адресов в django? Ниже приведены мои взгляды и URL-адреса. Как вы, вероятно, видите, в настоящее время существует два набора представлений и URL-адресов, которые были бы идентичными, если бы не другое название модели. Есть ли способ создать сразу 3 класса в качестве миксина или что-то подобное, чтобы все, что мне нужно было сделать, чтобы добавить новый набор классов, это передать имя модели одной функции или дочернему классу? Есть ли что-то подобное, что я мог бы сделать для URL-адресов? Я нашел связанный вопрос здесь Общие представления на основе классов и DRY, но я не уверен, применим ли и как ответ на этот вопрос здесь или актуален.
соответствующий раздел в представлениях:
class AlertMessageUpdate(LoginRequiredMixin, UpdateView):
template_name = "LibreBadge/applicationadmin/AlertMessage/alertMessageForm.html"
model = AlertMessage
fields = "__all__"
class AlertMessageCreate(LoginRequiredMixin, CreateView):
template_name = "LibreBadge/applicationadmin/AlertMessage/alertMessageForm.html"
model = AlertMessage
fields = "__all__"
class AlertMessageList(LoginRequiredMixin, ListView):
template_name = "LibreBadge/applicationadmin/AlertMessage/alertMessageList.html"
model = AlertMessage
class BadgeTemplateUpdate(LoginRequiredMixin, UpdateView):
template_name = "LibreBadge/applicationadmin/BadgeTemplate/badgeTemplateForm.html"
model = BadgeTemplate
fields = "__all__"
class BadgeTemplateCreate(LoginRequiredMixin, CreateView):
template_name = "LibreBadge/applicationadmin/BadgeTemplate/badgeTemplateList.html"
model = BadgeTemplate
class BadgeTemplateList(LoginRequiredMixin, ListView):
template_name = "LibreBadge/applicationadmin/BadgeTemplate/badgeTemplateList.html"
model = BadgeTemplate
соответствующий раздел в urls.py:
url(r'^applicationadmin/alertmessages/update/(?P<pk>[-\w]+)/$', views.AlertMessageUpdate.as_view(), name='AlertMessageUpdate'),
url(r'^applicationadmin/alertmessages/create/$', views.AlertMessageCreate.as_view(), name='AlertMessageCreate'),
url('applicationadmin/alertmessages/$', views.AlertMessageList.as_view(), name='AlertMessageList'),
url(r'^applicationadmin/badgetemplates/update/(?P<pk>[-\w]+)/$', views.BadgeTemplateUpdate.as_view(), name='BadgeTemplateUpdate'),
url(r'^applicationadmin/badgetemplates/create/$', views.BadgeTemplateCreate.as_view(), name='BadgeTemplateCreate'),
url('applicationadmin/badgetemplates/$', views.BadgeTemplateList.as_view(), name='BadgeTemplateList'),
Ответ на этот вопрос будет использован в LibreBadge , LibreBadge GitHub, решении для идентификационных бейджей с открытым исходным кодом, лицензированным MIT. Не стесняйтесь отвечать на этот вопрос в форме запроса на включение, если это ваш стиль!
Я нашел решение проблемы с повторяющимися просмотрами!
def applicationAdminCRUDFunction(model, modelName, fields):
def templateNameGenerator(suffix):
return("LibreBadge/applicationadmin/" + modelName + "/" + modelName + suffix + ".html")
viewsDictionary = {}
viewsDictionary['CreateView'] = type(modelName + 'CreateView', (CreateView,), {'template_name': templateNameGenerator('Form'),'model': model, 'fields': fields})
viewsDictionary['ListView'] = type(modelName + 'ListView', (ListView,), {'template_name': templateNameGenerator('List'),'model': model})
viewsDictionary['UpdateView'] = type(modelName + 'UpdateView', (UpdateView,), {'template_name': templateNameGenerator('Form'),'model': model, 'fields': fields})
viewsDictionary['DeleteView'] = type(modelName + 'DeleteView', (CreateView,), {'success_url': reverse_lazy(modelName + 'Create'),'model': model})
return(viewsDictionary)
AlertMessageViews = applicationAdminCRUDFunction(AlertMessage, 'AlertMessage', '__all__')
BadgeTemplateViews = applicationAdminCRUDFunction(BadgeTemplate, 'BadgeTemplate', '__all__')
Я создал функцию, которая использует тип для динамического создания представлений на основе классов (узнайте больше об использовании типов для создания классов здесь) и назначает их словарю.
Теперь мне нужно только вызвать функцию applicationAdminCRUDFunction и присвоить ее значения переменной. Затем я могу вызывать представления в urls.py так:
url(r'^alertmessages/update/(?P<pk>[-\w]+)/$', views.AlertMessageViews.get('UpdateView').as_view(), name='AlertMessageUpdate'),
Чтобы решить проблему с повторяющимся шаблоном URL, я создал функцию для возврата списка URL-адресов с параметром modelName.
def applicationAdminURLS(modelName):
return[
path(modelName + '/create', eval('views.' + modelName + 'Views' + ".get('CreateView').as_view()"), name= modelName + 'Create'),
path('', eval('views.' + modelName + 'Views' + ".get('ListView').as_view()"), name= modelName + 'List'),
path(modelName + '/update/(<int:pk>/', eval('views.' + modelName + 'Views' + ".get('UpdateView').as_view()"), name= modelName + 'Update'),
]
Затем я вызвал эту функцию, создав один шаблон пути с помощью include и передал функцию applicationAdminURLS в качестве параметра для включения.
path('alertmessages/', include(applicationAdminURLS('AlertMessage')), name='alertmessages'),
path('badgetemplates/', include(applicationAdminURLS('BadgeTemplate')), name='badgetemplates'),