Search code examples
pythondjangodjango-1.11django-viewflow

Overwrite django view with custom context (Django 1.11, Viewflow)


I have a Django 1.11 project using Viewflow - https://github.com/viewflow/viewflow - that I've incorporated. It's been very helpful, but a lot of stuff is kind of "magic", and being my first serious Django project, I'm running into an issue I'm not sure of how to solve, or the best way.

I have a generic template that expects a lot of context. I have a function that adds this context to all of my views:

def add_general_context(context, MOC, MOC_enabled_fields = (), MOC_status = None):
  context['MOC'] = MOC
  context['current_date'] = timezone.now().strftime("%D")
  context['MOC_form'] = forms.MOCForm(prefix="MOC_form", MOC_enabled_fields=MOC_enabled_fields, instance=MOC)
  context['MOCAttachments'] = models.MOCAttachment.objects.filter(MOC=MOC)
  context['MOCAttachment_form'] = forms.MOCAttachmentForm(prefix="MOCAttachment_form")
  context['MOCApprovals'] = models.MOCApproval.objects.filter(MOC=MOC)
  context['MOCTasks'] = models.MOCTask.objects.filter(MOC=MOC)
  context['MOC_status'] = MOC_status
  context['MOCConversation'] = models.MOCConversation.objects.filter(MOC=MOC)
  # Add comments to the conversation
  for conversation in context['MOCConversation']:
    conversation.comments = models.MOCComment.objects.filter(conversation=conversation)
  context['MOCComment_form'] = forms.MOCCommentForm(MOC=MOC)
  context['MOCCommentReply_form'] = forms.MOCCommentReplyForm()

I basically need to add this context to a view that is inside viewflow - namely, AssignTaskView - https://github.com/viewflow/viewflow/blob/f50accb3cde5d53f1d4db0debf5936867712c3bd/viewflow/flow/views/task.py#L109

I've tried a few things to overwrite/add to the context, but none seem to work.

Attempt 1: Overwrite the URL and use extra_context (SO suggested this)
- The issue is that the urls are "magic", my urlpatterns is very simply:

from material.frontend import urls as frontend_urls
urlpatterns = [
  url(r'^MOC/', include('MOC.urls')),
  url(r'', include(frontend_urls)),
]

Overwriting the urls themselves was WAY over my head, I dug into it for a while, but it uses really generic functions to pull in modules, etc. I didn't have a clue how to really even attempt it.

Attempt 2: Overwrite the view itself and the get_context_data function
I think this would be possible, but it just doesn't seem to work. My attempts looked similar to this (the lastest one):

from viewflow.flow.views.task import AssignTaskView as CoreAssignTaskView

class AssignTaskView(CoreAssignTaskView):
  def get_context_data(self, **kwargs):
    context = super(AssignTaskView, self).get_context_data(**kwargs)
    print("Did it work?")
    return context

This is in my views.py - however, it simply doesn't run. I'm probably missing something, but I can't figure out how to actually force it to use my view instead of the one built in to viewflow.

I've successfully overwritten Viewflow's templates without issue, but overwriting anything else is beyond me. Any suggestions?


Solution

  • Yes you can actually override a view url by putting it on top of url_patterns

    urlpatterns = [
        url(
            r'^/workflow/appname/flowname/(?P<process_pk>\d+)/taskname/(?P<task_pk>\d+)/assign/$',
            YouCustomView.as_view(),
            {'flow_task': FlowClass.taskname},
            name="{}__assign".format(self.name)))
        ),
        url(r'', include(frontend_urls)),
    ]
    

    But it's simpler just to create a custom flow.View subclass and set you own Assign View

    https://github.com/viewflow/viewflow/blob/master/viewflow/flow/nodes.py#L306

    from viewflow import flow
    
    class MyView(flow.View):
          assign_view_class = MyAssignTaskView
    

    flows.py:

     class MyFlow(Flow):
        ...
        taskname = MyView(UpdateProcessView).next(this.end)
    

    That's how you can override any of the built-in views.

    Viewflow designed to provide all knobs within your codebase. You can customize any behavior by subclassing Flow or flow Node classes.

    The custom node example could be helpful

    https://github.com/viewflow/viewflow/blob/master/demo/customnode/nodes.py