【问题标题】:Add argument to all views without having to edit them all to include variable in Django向所有视图添加参数,而无需全部编辑它们以在 Django 中包含变量
【发布时间】:2020-04-15 08:05:20
【问题描述】:

我需要什么

我正在为现有的 Django 项目开发一个拉取通知系统。从 100 多个视图开始,我正在寻找一种方法将参数(通知查询集)合并到所有视图中,因为这会呈现到我的 base.html 中,我可以通过将其传递到视图的参数字典中来做到这一点。

问题

我想在不编辑所有视图的情况下执行此操作,因为这会花费很长时间,并且所有未来的视图都需要包含此变量。

我的尝试

创建一个模板过滤器并将 request.user 作为变量传入以返回该用户的通知。这可行,但是当用户选择“新”通知时,我想向服务器发送一个信号,以将它们重定向到通知链接并将查看状态更改为“真”(POST 或 AJAX)。这需要特定视图知道如何处理该特定请求。

我的考虑

• 在 Django 中编辑最核心的“视图”。

我已尽力解释该问题,但如果需要更多信息,请随时询问。

谢谢!

models.py

class NotificationModel(models.Model):

    NOTIFICATION_TYPES = {'Red flag':'Red flag'}
    NOTIFICATION_TYPES = dict([(key, key) for key, value in NOTIFICATION_TYPES.items()]).items()

    notification_type = models.CharField(max_length=50, choices=NOTIFICATION_TYPES, default='')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created = models.DateTimeField(blank=True, null=True)
    text = models.CharField(max_length=500, default='')
    viewed = models.BooleanField(default=False)

views.py示例

class HomeView(TemplateView):
    template_name = 'app/template.html'

    def get(self, request, *args, **kwargs):
        notifications = NotificationsModel.objects.filter(user=request.user)
        args={'notifications':notifications}
        return render(request, self.template_name, args)

    def notification_handler(self, request)
        if 'notification_select' in request.POST:
            notification_id = request.POST['notification_id']
            notification = NotificationModel.objects.get(id=notification_id)
            notification.viewed = True
            notification.save()
            return redirect #some_url based on conditions

    def post(self, request, *args, **kwargs):
        notifications = self.notification_handler(request, *args, **kwargs)
        if notifications:
            return notifications

        return self.get(self, request)

【问题讨论】:

  • 我不明白这个问题,也许一些例子会有所帮助

标签: python django


【解决方案1】:

从 100 多个视图开始,我正在寻找一种方法将参数(通知查询集)合并到所有视图中,因为这会呈现到我的 base.html 中,我可以通过将其传递到视图的参数字典。

您不必将它放在视图中(实际上,您不应该 - 视图不应该处理无关的责任) - 您只需编写 simple custom template tag 来获取和呈现您需要的任何内容在您的基本模板中。这是正确的“django-esque”解决方案 FWIW,因为它使您的视图与此功能完全分离。

【讨论】:

  • 感谢您的回复!我已经这样做了,但是我不知道这是这样做的正确方法。在处理响应方面,我是否应该创建一个单独的类,所有通知选择都在其中。通过 url 传递通知 id?喜欢python url(r'^notification/(?P<notificationid>\d+)/$', views.NotificationRedirect.as_view(), name="notification_redirect"),
  • @LewisHepburn 是的,这基本上就是这个想法 - 必须在所有视图中显示的事物的自定义标签和作为处理特定请求的端点的特定视图。
【解决方案2】:

你考虑过mixins 吗?

class NotificationMixin:
    my_var = 'whatever'
class MyDjangoView(NotificationMixin,.....,View)
    pass

更好,使用 django 内置..

from django.views.generic import base

class NotificationMixin(base.ContextMixin):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['notification'] = 'whatever'    
        return context

并将此 mixin 与您的所有视图一起使用作为 FIRST CLASS INHERITED,请参阅 this。

对于您的情况,键入它而不是将其应用于基类更好,基视图类不是要更改的,而是要扩展的,这就是我们可以通过此解决问题的原因...

from django.generic.views import View as DjangoBaseView
from .mixins import NotificationMixin


class View(NotificationMixin, DjangoBaseView):
    pass

并使用任何 IDE 将所有导入的 Views 更改为您的 View 而不是 django。

【讨论】:

  • @ahmed-i-elsayed 感谢您的回答 ahmed,但我需要将此 Mixin 应用于所有视图。我可以以某种方式将它应用于基类吗?我所有的观点都继承自一个。选择通知后,我将如何处理发布请求。 (更新问题以包含代码)
猜你喜欢
  • 2014-10-11
  • 2013-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
  • 1970-01-01
  • 2011-06-08
相关资源
最近更新 更多