Cannot redirect when Django model class is mocked

2024/5/20 7:52:06

I have a view here which adds a new List to the database and redirects to the List page. I have get_absolute_url configured in the model class. It seems to works perfectly.

def new_list(request):form = ItemForm(request.POST)if form.is_valid():list_ = List()list_.owner = request.userlist_.save()form.save(for_list=list_)return redirect(list_)else:return render(request, 'home.html', {'form': form})

But the problem happens when I try to mock the model class and the form class with patch from unitest.mock

class TestMyLists(TestCase):@patch('lists.views.List')@patch('lists.views.ItemForm')def test_list_owner_is_saved_if_user_is_authenticated(self, mockItemFormClass, mockListClass):user = User.objects.create(email='[email protected]')self.client.force_login(user)self.client.post('/lists/new', data={'text': 'new item'})mock_list = mockListClass.return_valueself.assertEqual(mock_list.owner, user)

When I run the test, I get error like this:

Traceback (most recent call last):
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in innerresponse = get_response(request)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_responseresponse = self.process_exception_by_middleware(e, request)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_responseresponse = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/mnt/BAC4BB93C4BB4FFD/codes/tdd/superlists/lists/views.py", line 36, in new_listreturn redirect(list_)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/shortcuts.py", line 58, in redirectreturn redirect_class(resolve_url(to, *args, **kwargs))
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/http/response.py", line 407, in __init__self['Location'] = iri_to_uri(redirect_to)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/utils/encoding.py", line 151, in iri_to_urireturn quote(iri, safe="/#%[]=:;$&()+,!?*@'~")
File "/usr/local/lib/python3.6/urllib/parse.py", line 787, in quotereturn quote_from_bytes(string, safe)
File "/usr/local/lib/python3.6/urllib/parse.py", line 812, in quote_from_bytesraise TypeError("quote_from_bytes() expected bytes")
TypeError: quote_from_bytes() expected bytes

It seems like the redirect function will not work with a mock object. How can I fix this? I'm using Django 2.0.1

Answer

I'm learning the same tutorial, and i got the same error, however i find the solution here: Mock() function gives TypeError in django2

The cause is:

Django 2 doesn't support anymore bytestrings in some places so when the views redirect the mock Class List it does as a mock object and the iri_to_uri django function throws an error.

In django 1.11 iri_to_uri forced the iri to a bytes return quote(force_bytes(iri), safe="/#%[]=:;$&()+,!?@'~") instead now is return quote(iri, safe="/#%[]=:;$&()+,!?@'~").

So the solution is to return redirect(str(list_.get_absolute_url())) instead of return redirect(list_) in the lists.views.py

Here is my example:

def new_list(request):form = ItemForm(data=request.POST)if form.is_valid():list_ = List()list_.owner = request.userlist_.save()form.save(for_list=list_)return redirect(str(list_.get_absolute_url()))else:return render(request, 'home.html', {"form": form})
https://en.xdnf.cn/q/73244.html

Related Q&A

How to make a Pygame Zero window full screen?

I am using the easy-to-use Python library pgzero (which uses pygame internally) for programming games.How can I make the game window full screen?import pgzrunTITLE = "Hello World"WIDTH = 80…

Check if one series is subset of another in Pandas

I have 2 columns from 2 different dataframes. I want to check if column 1 is a subset of column 2.I was using the following code:set(col1).issubset(set(col2))The issue with this is that if col1 has onl…

How to change the head size of the double head annotate in matplotlib?

Below figure shows the plot of which arrow head is very small...I tried below code, but it didnot work... it said " raise AttributeError(Unknown property %s % k) AttributeError: Unknown propert…

Passing a firefox profile to remote webdriver firefox instance not working

Im trying to start up a remote webdriver instance of Firefox and pass in a profile.profile = webdriver.FirefoxProfile() profile.set_preference("browser.download.folderList","2") sel…

Tensorflow 2.3.0 does not detect GPU

The tensorflow does not detect the GPU card. I have following the procedures suggest at Nvidia website and tensorflow/install/gpu. How can I fix it? I am using the following packages and drives: NVIDI…

How to create dict from class without None fields?

I have the following dataclass:@dataclass class Image:content_type: strdata: bytes = bid: str = ""upload_date: datetime = Nonesize: int = 0def to_dict(self) -> Dict[str, Any]:result = {}if…

Is sys.exit equivalent to raise SystemExit?

According to the documentation on sys.exit and SystemExit, it seems thatdef sys.exit(return_value=None): # or return_value=0raise SystemExit(return_value)is that correct or does sys.exit do something …

Vertical overflow of table in live display should scroll the content

Im using a Live display to show the content of a Table which grows over time. Eventually there is a vertical overflow and in that case Id like the oldest (i.e. topmost) rows to vanish while the most re…

Reading KML Files Using Fastkml

Ive searched around quite a bit for this specific Python module, and havent been able to find a source which points me in the right direction.Im trying to read a KML file and display all of the feature…

Adding extra fields to django-registration form

I have a model called "Organization" that Ive setup as a User profile and I would like to have the fields from the "Organization" model show up on the registration page. How do I go…