wrufesh
wrufesh

Reputation: 1406

django cant use global variable in class based view

my view is like this

class RecordView(View):
    record_form = RecordForm
    record_files = {}
    templare = 'acquisition.html'

    def get(self, request, *args, **kwargs):
        fil = urllib.urlopen('/home/student/wwww.jpg')
        self.record_files = {'small_cover': SimpleUploadedFile('hehe.jpg', fil.read())}
        rr_form = self.record_form()
        return render(request, self.template_name, {'rr_form': rr_form,
                                            })
    def post(self, request, *args, **kwargs):
        record = RecordForm(request.POST, self.record_files)
        record.save()
        HttpResponseRedirect('/')

Here i have populated self.record_files in get method.. but after i post data i see self.record_files as empty dictionary. I get confused here. What can i do to do so.

Upvotes: 1

Views: 1982

Answers (2)

Ben Murden
Ben Murden

Reputation: 630

The state of your view instance is not maintained between a get and a post, so setting record_files on the instance will not keep it for the next request. You would need to put that logic in the dispatch method, or store information in the user's session.

class RecordView(View):
    record_form = RecordForm
    record_files = {}
    templare = 'acquisition.html'

    # dispatch is called before deciding whether to use get() or post()
    # so any instance-level properties that require the request can go here.
    # This could even go in __init__().
    def dispatch(self, request, *args, **kwargs):
        fil = urllib.urlopen('/home/student/wwww.jpg')
        self.record_files = {'small_cover': SimpleUploadedFile('hehe.jpg', fil.read())}
        return super(RecordView, self).dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        rr_form = self.record_form()
        return render(request, self.template_name, {'rr_form': rr_form,
                                        })

    # self.record_files will be available in a get, or a post (or any valid 
    # method for that matter).
    def post(self, request, *args, **kwargs):
        record = RecordForm(request.POST, self.record_files)
        record.save()
        return HttpResponseRedirect('/')

Upvotes: 3

lehins
lehins

Reputation: 9767

That is exactly how it suppose to work. Whenever you have a GET request, it will call method get, and if it is a POST request, naturally it will call post method, but not the get method. So here is how you can solve your problem:

from django.views.generic import TemplateView

class RecordView(TemplateView):
    record_form = RecordForm
    record_files = {}
    template_name = 'acquisition.html'

    def get_context_data(self, **context):
        fil = urllib.urlopen('/home/student/wwww.jpg')
        self.record_files = {
            'small_cover': SimpleUploadedFile('hehe.jpg', fil.read())
        }
        context.update({
            'record_files': self.record_files,
            'rr_form': self.record_form()
        })
        fil.close()
        return super(RecordView, self).get_context_data(**context)

    def post(self, request, *args, **kwargs):
        context = self.get_context_data()
        record_form = self.record_form(request.POST, self.record_files)
        if record_form.is_valid():
             record_form.save()
        ## or do a redirect instead, like you had before:
        # return HttpResponseRedirect('/')
        context['rr_form'] = record_form
        return self.render_to_response(context)

Upvotes: 0

Related Questions