Как я могу использовать instaceof в шаблоне Django?

#python #django #class

#python #django #класс

Вопрос:

Здравствуйте, у меня есть шаблон, который используется двумя представлениями в этом шаблоне, у которого есть переключатель для удаления объектов, и поскольку у меня есть 2 типа объектов, которые могут быть удалены одной и той же формой, я хочу каким-то образом проверить экземпляр объекта, чтобы решить, какой URL использовать для удаления. Как я могу правильно написать это в шаблоне django?

  <form method="POST" action="{% if object instanceof Income %}{% url 'delete-income' object.id %}{% elif object instanceof Spending %}{% url 'delete-spending' object.id %}{% endif %}">
 

представления расширяют этот пользовательский микс, чтобы не повторять код:

 class ObjectDeleteViewMixin(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = None
    template_name = 'users/incomes_amp;_spendings.html'
    success_url = None


    def test_func(self):
        self.model = self.get_object()
        if self.request.user == self.model.user:
            return True
        return False
 

представления

 class IncomeDeleteView(ObjectDeleteViewMixin):
    model = Income
    success_url = reverse_lazy('incomes')


class SpendingDeleteView(ObjectDeleteViewMixin):
    model = Spending
    success_url = reverse_lazy('spendings')
 

url-адреса:

 path('incomes/delete/<int:pk>/', IncomeDeleteView.as_view(), name='delete-income'),
    path('spendings/delete/<int:pk>/', SpendingDeleteView.as_view(), name='delete-spending'),
 

Комментарии:

1. Пожалуйста, не делайте этого. Это не относится к шаблону, это бизнес-логика. Кроме того, довольно странно, что объект может быть двух разных типов, хотя это и не запрещено, но часто это не очень хорошая идея.

2. Вероятно, здесь лучше просто реализовать метод для каждого класса, который указывает на URL-адрес удаления.

3. Я думал о чем-то подобном, чтобы создать только один URL-адрес для удаления объектов, потому что процесс тот же, но я действительно не знаю, как я могу достичь этого в django

4. Я добавлю свои взгляды в вопрос и URL-адреса, не могли бы вы мне помочь, пожалуйста?

5. Вы можете создать пользовательский фильтр шаблона. Но, как сказал @Willem Van Onsem, это не рекомендуется.

Ответ №1:

Пожалуйста, не делайте этого. Шаблоны Django намеренно ограничены, чтобы не разрешать вызовы функций, подписку и т. Д., Чтобы люди не могли писать бизнес-логику в шаблоне. Шаблон обычно ориентирован на логику рендеринга. Реализуя бизнес-логику в шаблоне, вы часто усложняете понимание шаблонов, их обновление и т. Д.

Вероятно, самый элегантный способ решить эту проблему — определить метод как Income в классе, так и в Spending классе, который возвращает путь к URL-адресу удаления:

 from django.urls import reverse

class Income(models.Model):
    # …

    def remove_url(self):
        return reverse('delete-income', kwargs={'pk': self.pk})

# …

class Spending(models.Model):
    # …

    def remove_url(self):
        return reverse('delete-spending', kwargs={'pk': self.pk}) 

затем вы можете визуализировать это с помощью:

 <form method="POST" action="{{ object.remove_url }}"> 

Комментарии:

1. Спасибо за идею, но как насчет URL-адресов? Как я должен их писать?

2. Или я оставлю их как есть

3. @ARYAN: мы уже написали их. Вызывая object.remove_url , мы получим результат reverse('delete-income', kwargs={'pk': self.pk}) , например, который является путем.

4. Теперь я понял, я его реализовал, но теперь он выдает мне такую ошибку: «Объект ‘Income’ не имеет атрибута ‘_default_manager'»

5. @ARYAN: но обычно это не имеет ничего общего с отображением объекта удаления, вероятно, потому, что вы пишете self.model = self.get_object() , поскольку self.model now — это объект , который вы не должны изменять self.object .