Search code examples
djangodjango-viewsdjango-class-based-viewspython-class

Attibutes are 'disappearing' from CBV. Django


I am trying to build CBV with class View parent. This view takes slug of object and find that object between two django models. The functions from services.py was doing a lot of DB queries, so, I tried to reduce them by giving to FeedbackSection necessary attributes(slug, model_instance and context) and lately override them in get method.

class FeedbackSection(View):
    """
    Feedback section for different objects.

    This is something like 'generic' view, so I implement it that it will find
    the model and feedbacks for this model by having only slug.
    """

    template_name = 'feedbacks/feedback-section.html'
    form_class = CreateFeedbackForm
    slug = None
    model_instance = None
    context = None

    def get(self, request, *args, **kwargs):
        self.slug = kwargs.get('slug')
        self.model_instance = get_model_instance(self.slug)
        self.context = get_feedback_section_context(self.slug, self.form_class, self.model_instance)
        return render(request, self.template_name, self.context)

    @method_decorator(login_required)
    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            # will create feedback object and update model[Advert, Company] rating.
            end_feedback_post_logic(self.request.user, form, self.model_instance)
        return render(request, self.template_name, self.context)

The attributes(slug, model_instance and context), when post method is in runtime are equivalent to None. The problem is that this implementation was working fine yesterday, but today it's not.

I know I can use my functions again, but in post method. I don't want to do this. Because it will multiple DB Queries by two.


Solution

  • We need to override the setup method of the View class and define those attributes there.

    def setup(self, request, *args, **kwargs):
        self.slug = kwargs.get('slug')
        self.model_instance = get_model_instance(self.slug)
        self.context = get_feedback_section_context(
            self.slug,
            self.form_class,
            self.model_instance
        )
        return super().setup(request, *args, **kwargs)