[Django]-AttributeError: can't set attribute

116👍

This answer doesn’t address the specifics of this question, but explains the underlying issue.
This specific exception "AttributeError: can’t set attribute" is raised (see source) when the attribute you’re attempting to change is actually a property that doesn’t have a setter. If you have access to the library’s code, adding a setter would solve the problem.

EDIT: updated source link to new location in the code.

Edit2:

Example of a setter:

class MAMLMetaLearner(nn.Module):
    def __init__(
            self,
            args,
            base_model,

            inner_debug=False,
            target_type='classification'
    ):
        super().__init__()
        self.args = args  # args for experiment
        self.base_model = base_model
        assert base_model is args.model

        self.inner_debug = inner_debug
        self.target_type = target_type

    @property
    def lr_inner(self) -> float:
        return self.args.inner_lr

    @lr_inner.setter
    def lr_inner(self, new_val: float):
        self.args.inner_lr = new_val

0👍

It looks like you don’t use self.template in Response class. Try like this:

class Response(HttpResponse):
    def __init__(self, template='', calling_context='' status=None):
        HttpResponse.__init__(self, get_template(template).render(calling_context), status)

0👍

I took a look to django source code I’ve no idea where template or templates attribute come from in HttpResponse. But I can propose to you to change your test approach and migrate to mock framework. You can rewrite your test like:

@patch("qualified_path_of_response_module.response.Response", spec=Response)
def test_should_list_all_users_for_that_specific_sales_office(self,mock_resp):
    user_company = CompanyFactory.create()
    request = self.mock_request(user_company)
    #some other stuff

    #calling the view
    response = show(request, sales_office_id=sales_office.id)
    self.assertTrue(mock_resp.called)
    context = mock_resp.call_args[0][2]
    self.assertIn(user, context["sales_office_users"])
    self.assertNotIn(user2, context["sales_office_users"])

@patch decorator replace your Response() class by a MagicMock() and pass it to your test method as mock_resp variable. You can also use patch as context manager by with construct but decorators are the cleaner way to do it. I don’t know if Response is just a stub class for testing but in that case you can patch directly HttpResponce, but it depends from your code.

You can find details about call_args here. Maybe you need to use spec attribute because django make some type checking… but try with and without it (I’m not a django expert). Explore mock framework: it’ll give to you lot of powerful tools to make simple tests.

Leave a comment