djangodjames
djangodjames

Reputation: 319

How to pass a variable between methods inside Django class based View

I have a class that gets the data from the form, makes some changes and save it to the database.

I want to have several method inside.

I want the post method to save the data from the form to the database and pass the instanse variable to the next method. The next method should make some changes, save it to the databese and return redirect.

But I have an error. 'Site' object has no attribute 'get' Here is my code:

class AddSiteView(View):
    form_class = AddSiteForm
    template_name = 'home.html'

    def get(self, request, *args, **kwargs):
        form = self.form_class()
        return render(request, self.template_name, { 'form': form })
    
    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            # Get website url from form
            site_url = request.POST.get('url')
            
            # Check if the site is in DB or it's a new site
            try:
                site_id = Site.objects.get(url=site_url)
            except ObjectDoesNotExist:
                site_instanse = form.save()
            else:
                site_instanse = site_id
            return site_instanse
        
        return render(request, self.template_name, { 'form': form })

    def get_robots_link(self, *args, **kwargs):

        # Set veriable to the Robot Model
        robots = Robot.objects.get(site=site_instanse)

        # Robobts Link
        robots_url = Robots(site_url).get_url()
        robots.url = robots_url
        robots.save()    
        return redirect('checks:robots', robots.id, )

I need to pass site_instanse from def post to def get_robots_link

Here is the traceback:

Internal Server Error: /add/
Traceback (most recent call last):
  File "/home/atom/.local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/atom/.local/lib/python3.8/site-packages/django/utils/deprecation.py", line 96, in __call__
    response = self.process_response(request, response)
  File "/home/atom/.local/lib/python3.8/site-packages/django/middleware/clickjacking.py", line 26, in process_response
    if response.get('X-Frame-Options') is not None:
AttributeError: 'Site' object has no attribute 'get'
[14/Jul/2020 10:36:27] "POST /add/ HTTP/1.1" 500 61371

Here is the place where the problem is: If I use redirect inside the post method. Everything works good. Like so:

class AddSiteView(View):
    form_class = AddSiteForm
    template_name = 'home.html'

    def get(self, request, *args, **kwargs):
        form = self.form_class()
        return render(request, self.template_name, { 'form': form })
    
    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            # Get website url from form
            site_url = request.POST.get('url')
            
            # Check if the site is in DB or it's a new site
            try:
                site_id = Site.objects.get(url=site_url)
            except ObjectDoesNotExist:
                site_instanse = form.save()
            else:
                site_instanse = site_id
            
            # Set veriable to the Robot Model
            robots = Robot.objects.get(site=site_instanse)

            # Robobts Link
            robots_url = Robots(site_url).get_url()
            robots.url = robots_url
            robots.save()    
            return redirect('checks:robots', robots.id, ) ## HERE
        
        return render(request, self.template_name, { 'form': form })

But if remove the line return redirect('checks:robots', robots.id, ) from the post method and put return self.site_instance there. and add the def get_robots_link. It give the error: 'Site' object has no attribute 'get'

Upvotes: 1

Views: 1299

Answers (2)

Alexandr Tatarinov
Alexandr Tatarinov

Reputation: 4034

One must return a response from the post method. This code returns a Site instance on these lines. Not sure what is the intended behavior, either a redirect or render should be used.

        try:
            site_id = Site.objects.get(url=site_url)
        except ObjectDoesNotExist:
            site_instanse = form.save()
        else:
            site_instanse = site_id
        return site_instanse

Upvotes: 0

Aayush Agrawal
Aayush Agrawal

Reputation: 1394

class AddSiteView(View):
    form_class = AddSiteForm
    template_name = 'home.html'

    def get(self, request, *args, **kwargs):
        form = self.form_class()
        return render(request, self.template_name, { 'form': form })
    
    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            # Get website url from form
            site_url = request.POST.get('url')
            
            # Check if the site is in DB or it's a new site
            try:
                site_id = Site.objects.get(url=site_url)
            except ObjectDoesNotExist:
                site_instanse = form.save()
            else:
                site_instanse = site_id
                self.site_instance = site_instanse #See this
            return site_instanse
        
        return render(request, self.template_name, { 'form': form })

    def get_robots_link(self, *args, **kwargs):

        # Set veriable to the Robot Model
        robots = Robot.objects.get(site=self.site_instance)

        # Robobts Link
        robots_url = Robots(site_url).get_url()
        robots.url = robots_url
        robots.save()    
        return redirect('checks:robots', robots.id, )

Use self to encode the data within the object

Upvotes: 1

Related Questions