Search code examples
django-urlsdjango-class-based-viewsdjango-generic-views

Refeencing a parameter from a related model object inside a DeleteView to pass to my get_success_url?


I have this model, related with my User schema model:

class EntrepreneurshipOffer(models.Model):

    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
...

In addition, I have a view named EntrepreneurshipOffersByUser which let me list all offers that I've created

class EntrepreneurshipOffersByUser(LoginRequiredMixin, UserProfileDataMixin, ListView):
    template_name = 'entrepreneurship/my_entrepreneurship_offer_list.html'

    def get_queryset(self, *args, **kwargs):
        user = self.request.user
        queryset_list = EntrepreneurshipOffer.objects.filter(created_by__username=user.username)
        return queryset_list

    def get_context_data(self, **kwargs):
        context = super(EntrepreneurshipOffersByUser, self).get_context_data(**kwargs)
        user = self.request.user
        entrepreneurship_offers = EntrepreneurshipOffer.objects.filter(created_by__username=user.username)
        context['offers_by_user'] = entrepreneurship_offers
        return context

The URLs to view my EntrepreneurshipOffer objects are:

# Main URL which call to Entrepreneurship Offer URLs
url(r'^offer/entrepreneurship/', include('entrepreneurship.urls', namespace='offer')),

# List Entrepreneurship Offer's user
    url(r'^by/u/(?P<username>[-\w]+)/$',
        EntrepreneurshipOffersByUser.as_view(),
        name='list'),
    ]

My question is related to the goal of delete EntrepreneurshipOffer and after, redirect the workflow to my EntrepreneurshipOffer list objects mentioned above.

I have the EntrepreneurshipOfferDeleteView class-based view with the get_success_url method, in which I call the url to list my objects passing the namespace and the URL name mentioned above, adding the username parameter required by the URL

class EntrepreneurshipOfferDeleteView(SuccessMessageMixin, UserProfileDataMixin, LoginRequiredMixin, DeleteView):
    model = EntrepreneurshipOffer
    #success_url = reverse_lazy("offer:list")
    success_message = "Oferta de emprendimiento eliminada con éxito"

    def get_success_url(self):
        entrepreneurship_offer = self.get_object()
        #print(entrepreneurship_offer)
        return reverse_lazy("offer:list", kwargs={'created_by': entrepreneurship_offer.created_by.username})

I need to pass the username parameter, but it seems I am not doing of a suited way, because, despite that the username parameter it's added to the workflow, via self.get_object() I get this error:

NoReverseMatch at /offer/entrepreneurship/modelo-de-negocio/delete/
Reverse for 'list' with arguments '()' and keyword arguments '{'created_by': 'bgarcial'}' not found. 1 pattern(s) tried: ['offer/entrepreneurship/by/u/(?P<username>[-\\w]+)/$']

I'm new to class-based views so I'm sure there is an obvious fix for this, but I haven't found it yet.

Any help is much appreciated. Thanks.


Solution

  • Your url is defined like this:

    url(r'^by/u/(?P<username>[-\w]+)/$',
        EntrepreneurshipOffersByUser.as_view(),
        name='list'),
    ]
    

    thus it requires a username parameter. However, you try to call it like
    reverse_lazy("offer:list", kwargs={'created_by': entrepreneurship_offer.created_by.username}) i.e using created_by. Try changing it to

    reverse_lazy("offer:list", kwargs={'username': entrepreneurship_offer.created_by.username}) and it should work (or at least it should throw a different error).