Using mixins with class-based views throwing error

Hi All,

I am new to programming and django, I am trying to use the below solution for accepting an input from the form in first accordion step, save to database and display those details in the next accordion step, but it is throwing the below error, can someone help on this?

https://docs.djangoproject.com/en/4.1/topics/class-based-views/mixins/#an-alternative-better-solution

AttributeError: Generic detail view WrkFlwDetailView must be called with either an object pk or a slug in the URLconf.

Thanks,
Sagar

Briefly, the error is saying that the url that you are defining for that view needs to specify a parameter in the url definition.

We can be more specific if you post your WrkFlwDetailView and the path in the urls.py file for it here.

(When posting code here, enclose the block of code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```.)

Hi Ken,

Below is entire code

class WrkFlwDetailView(generic.DetailView):
    model = WrkFlw
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = WrkFlwModelForm()
        return context
    
class WrkFlwFormView(generic.detail.SingleObjectMixin, generic.FormView):
    template_name = "wrkflwmgr/wrkflw_run.html"
    form_class = WrkFlwModelForm
    model = WrkFlw
    
    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return HttpResponseForbidden()
        self.objecct = self.get_object()
        return super().post(request,*args,**kwargs)
    
    def get_success_url(self) -> str:
        return reverse('wrkflw_run', kwargs={'pk': self.object.pk})

class WrkFlwView(View):
    #Display data in wrkflw_run.html using CBV with Form
    def post(self, request, *args, **kwargs):
        view = WrkFlwFormView.as_view()
        return view(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        view = WrkFlwDetailView.as_view()
        return view (request, *args, **kwargs)

Urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', HomePageView.as_view(), name='home_page'),
    path('login/', views.handlelogin, name='wrkflw_login'),
    path('logout/', views.handlelogout, name='wrkflw_logout'),
    path('wrkflw/', WrkFlwView.as_view(), name='wrkflw_run'),
    path('test/', testView.as_view(), name='test')
]

Below is the code:

class WrkFlwDetailView(generic.DetailView):
    model = WrkFlw
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = WrkFlwModelForm()
        return context
    
class WrkFlwFormView(generic.detail.SingleObjectMixin, generic.FormView):
    template_name = "wrkflwmgr/wrkflw_run.html"
    form_class = WrkFlwModelForm
    model = WrkFlw
    
    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return HttpResponseForbidden()
        self.objecct = self.get_object()
        return super().post(request,*args,**kwargs)
    
    def get_success_url(self) -> str:
        return reverse('wrkflw_run', kwargs={'pk': self.object.pk})

class WrkFlwView(View):
    #Display data in wrkflw_run.html using CBV with Form
    def post(self, request, *args, **kwargs):
        view = WrkFlwFormView.as_view()
        return view(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        view = WrkFlwDetailView.as_view()
        return view (request, *args, **kwargs)
   

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', HomePageView.as_view(), name='home_page'),
    path('login/', views.handlelogin, name='wrkflw_login'),
    path('logout/', views.handlelogout, name='wrkflw_logout'),
    path('wrkflw/', WrkFlwView.as_view(), name='wrkflw_run')
]

The view needs to know which instance of the object that it’s going to work with. The view requires that a parameter be passed to it. You need to add it to your definition here. That parameter must be named either pk or slug.

So I tried updating as below, but this won’t let /wrkflw load now as there is no pk present

path('<int:pk>/wrkflw/', WrkFlwView.as_view(), name='wrkflw_run'),

Just to give a glimpse of the goal I am trying to achieve here is, I am accepting few input in the first step and on start update them in the database, then the url should change to the /wrkflw/pk where pk is the id of that data in the database and at the same time it displays the entered data in the first step to second step for confirmation.

I have the attached the frontend snapshot too, Please let me know if I am in the right direction with this code or this is something to be done differently.

Thanks,
Sagar

I don’t know what you mean by this.

Yes, by adding the parameter, that means that you need to supply the parameter on the url where you’re trying to access that view.

ok, How do I do that?

How are you currently accessing that url?

From homepage when I click new workflow it takes me to below url

http://127.0.0.1:8000/wrkflw

when I access this it shows me the page with the frontend as previous post

So then you need to add the the pk of the item that you wish to work with.

Your url would end up being something like http://127.0.0.1:8000/7/wrkflw, if 7 is the pk of the object that you wish to look at.

understood that works perfectly for me when I manually enter the pk in url for which I have to access as long as that entry is already present in the database.

But my current requirement is when I enter new details in the form they need to save in database and at the same time the url should change auto to http://127.0.0.1:8000/pk/wrkflw where is pk is the entry for the data that got saved. Also I should able to present that data in the same page on next accordion.

I only have one html file named a wrkflw.html where I am trying to do this

Then you may need to work some JavaScript into this to update your current page without doing a full page refresh.

got it any directions on where i can refer that?

The general topic is referred to as AJAX, there is a ton of resources available.

Thank You so much for the guidance