tread
tread

Reputation: 11088

How to set instance variables in a class based view?

I want to check if a user is in a specific group on initilisation of the class based view.

Then use that variable in a number of methods like get_form()and get_context_data()

However I get an error:

File "/projects/hr_project/entries/views.py", line 117, in get_form_class
    if self.is_manager:
AttributeError: 'EntryCreateView' object has no attribute 'is_manager'

Here is the class based view:

class EntryCreateView(
        LoginRequiredMixin,
        FormView,
        MessagePermissionRequiredMixin,):
    '''Class based view to enter new timesheet entries
    '''
    form_class = None
    template_name = 'entries/entry_form.html'
    permission_required = None
    permission_denied_message = 'You do not have the permission to create an entry for that user'

    def dispatch(self, request, *args, **kwargs):
        # Initialise variables and check permissions once
        # Set the intial date
        if self.kwargs.get('date'):
            self.date = self.kwargs.get('date')
        else:
            self.date = self.get_form().fields['date'].initial

        self.date = str(self.date)
        self.date_val = datetime.strptime(self.date, '%Y-%m-%d')
        self.is_manager = False
        manager_group = Group.objects.get(name='Managers')
        if manager_group in request.user.groups.all():
            self.is_manager = True

        # Set the user and permission
        self.permission = True
        self.user = request.user
        if self.is_manager:
            # Check user is manager
            self.user = self.kwargs.get('user')
        else:
            if self.kwargs.get('user') == request.user.id:
                self.user = self.kwargs.get('user')
            else:
                self.permission = False
        super().dispatch(request, *args, **kwargs)

    def has_permission(self):
        ''''Override how permissions are checked
        '''
        return self.permission

    def get_context_data(self, *args, **kwargs):
        context_data = super().get_context_data(*args, **kwargs)
        return context_data

Upvotes: 0

Views: 620

Answers (2)

Alasdair
Alasdair

Reputation: 308779

I don’t think it’s a very good design to call get_form in your dispatch method - it already runs when you call super() so you are running the method twice.

If you do stick with this approach, you have to reorder your code. Currently you are trying to read self.is_manager when you call get_form(), but you don’t set the attribute until later in your dispatch method.

Upvotes: 1

fweidemann14
fweidemann14

Reputation: 1973

If I interpret that correctly, your problem is that is_manager is not available on the instances of your objects.

If is_manager is being declared as an instance variable in the dispatch method, it only gets set on an instance of that class when you call this specific method on it.

If you create an object a of your class, then perform an a.dispatch(your_arguments) you should be able to access a.is_manager properly.

Usually if you want your class to have instance variables, you do it in your classe's __init__ function, e.g:

class Test:
  def __init__(self):
    self.is_manager = False

Hope that helps.

Upvotes: 0

Related Questions