[Another Update:]
I solved this and posted an answer below but if anyone has a cleaner solution that would be welcome!
[Update]: I've been able to fix the problem with registration_complete by specifying a success_url in a custom MyRegistrationView. But this doesn't work for ActivationView and it's still throwing a NoReverseMatch error while looking for a 'django_registration_activate_complete' pattern. Updated code is below.
I'm trying to implement django-registration for my webapp, and am getting NoReverseMatch errors for both my 'django_registration_activation_complete' and 'django_registration_complete' views.
When I register a new user, instead of redirecting to my 'registration_complete' view after hitting submit, I get the following NoReverseMatch error (below). The email with the activation link sends properly, and when the activation link is clicked, the user is marked as active and can sign in. However, clicking the activation link leads to a similar NoReverseMatch error, and my 'activation_complete' template doesn't show.
I have a custom user model inheriting from AbstractUser, so I had to create my own user registration form, but aside from that I don't think I'm missing anything from the django-registration quickstart guide.
My templates are all in the folder 'C:\Projects\PyDev\group_work\users\templates\django_registration' and are named as described in the quickstart guide
This is my first question so please let me know if anything is unclear or missing.
Traceback (most recent call last):
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django_registration\views.py", line 52, in dispatch
return super().dispatch(*args, **kwargs)
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\views\generic\edit.py", line 142, in post
return self.form_valid(form)
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django_registration\views.py", line 96, in form_valid
return HttpResponseRedirect(self.get_success_url(self.register(form)))
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django_registration\views.py", line 93, in get_success_url
return super().get_success_url()
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\views\generic\edit.py", line 51, in get_success_url
if not self.success_url:
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\utils\functional.py", line 119, in __wrapper__
res = func(*self.__args, **self.__kw)
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\urls\base.py", line 87, in reverse
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "C:\Projects\PyDev\group_work\gw_env\lib\site-packages\django\urls\resolvers.py", line 677, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'django_registration_complete' not found. 'django_registration_complete' is not a valid view function or pattern name.
urls.py:
urlpatterns = [
path('accounts/register/', RegistrationView.as_view(
form_class=UserRegisterForm),
name = 'django_registration_register',),
path('accounts/activate/(?P<activation_key>\w+)/$',
ActivationView.as_view(),
name='django_registration_activate'),
path('accounts/',
include('django_registration.backends.activation.urls')),
]
[Edit] in views.py (the MyActivationView doesn't solve my problem)
class MyRegistrationView(RegistrationView):
success_url = reverse_lazy('users:django_registration_register_complete')
class MyActivationView(ActivationView):
success_url = reverse_lazy('login')
[Another Edit] this is also something I've tried, in urls.py, which didn't work:
path('activate/complete/', TemplateView.as_view(
template_name = 'django_registration/activation_complete.html'
), name='django_registration_activation_complete'),
I solved this by adding the success url path to my main urls.py, instead of the one in my app:
path('activate/complete/', TemplateView.as_view(
template_name='django_registration/activation_complete.html'
), name='django_registration_activation_complete'),
Related
I'm trying to create a custom "list" under OptionViewSet but It's giving me an error.
class OptionViewSet(viewsets.ModelViewSet):
serializer_class = OptionSerializer
queryset = Option.objects.all()
def list(self, request):
queryset = Option.objects.all()
serializer = OptionSerializer(queryset, many=True)
return Response(serializer.data)
Error
__init__() takes 1 positional argument but 2 were given
This works fine:
class OptionViewSet(viewsets.ModelViewSet):
serializer_class = OptionSerializer
queryset = Option.objects.all()
urls.py
path('api/shipping/', include((shipping_routes.urls, 'shipping'), namespace='shipping')),
routes.py
routes.register(r'option', OptionViewSet, basename='option')
serializer
class OptionSerializer(serializers.ModelSerializer):
class Meta:
model = Option
fields = ['id', 'extra', 'name']
full traceback
Traceback (most recent call last):
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\Simon\Documents\GitHub\crud-react-django\django_backend\shipping\views.py", line 18, in list
return Response(serializer.data)
Exception Type: TypeError at /api/shipping/option/
Exception Value: __init__() takes 1 positional argument but 2 were given
I had the wrong Response import. Imported it from "requests" instead of "rest_framework.response".
In the url.py, in the the specific path from urlpatters[] you need to call your views.OptionViewSet.as_view() as a middle parameter between the URL path and the name reference:
path('api/shipping/', include((shipping_routes.urls, 'shipping'), namespace='shipping')),
Django has very good documentation and you can read more about the Django-Rest-Framework's ViewSets here:
https://www.django-rest-framework.org/api-guide/viewsets/
edit: From the exception stack trace we can see that url.py is refering to a problem with /api/shipping/option/ which essentially is the routes.py's record with basename='option'
Seems like you might need to adjust routes.py from
routes.register(r'option', OptionViewSet, basename='option')
to
routes.register(r'option', OptionViewSet.as_view(), basename='option')
Can you please give it a go and let us know how it goes!
I am a Django beginner and a SOF newbie, sorry if this question sounds a silly to some.
I am struggling with my integration tests.
In my app I have a one-to-one User/Profile relationship. I have a list view to show registered users' profile data:
class ProfileListView(views.ListView, LoginRequiredMixin):
model = Profile
template_name = 'registration/profile_list.html'
paginate_by = 8
def get_context_data(self, *, object_list=None, **kwargs):
context = super(ProfileListView, self).get_context_data()
# superuser raises DoesNotExist at /accounts/profiles/ as they are created with createsuperuser in manage.py
# hence are not assigned a profile automatically => create profile for them here
try:
context['current_profile'] = Profile.objects.get(pk=self.request.user.pk)
except ObjectDoesNotExist:
Profile.objects.create(user=self.request.user)
context['current_profile'] = Profile.objects.get(pk=self.request.user.pk)
# get all other users' profiles apart from staff and current user
regular_users = User.objects \
.filter(is_superuser=False, is_staff=False, is_active=True) \
.exclude(pk=self.request.user.pk)
context['non_staff_active_profiles'] = Profile.objects.filter(user__in=regular_users)
return context
I want to test the get_context_data() method to ensure it returns:
correct logged in user
correct queryset of non-staff profiles
My test breaks as soon as I try something like:
response = self.client.get('/accounts/profiles/')
I understand I need to pass user/profile data to the client but I could not figure out how to do that. It looks like it fails because of context['current_profile'] = Profile.objects.get(pk=self.request.user.pk) and I have no idea why.
The whole 'test' is below:
def test_view_get_context_data__should_return_correct_context(self):
new_user = User.objects.create_user(**self.VALID_USER_DATA_1)
# create profile
new_profile = Profile.objects.create(user=new_user)
# test profile
self.assertEqual(new_profile.user_id, new_user.pk)
response = self.client.get('/accounts/profiles/')
It fails with:
/home/kk/Documents/Github/Phonotheque/venv/bin/python /snap/pycharm-professional/280/plugins/python/helpers/pycharm/django_test_manage.py test Phonotheque.accounts_app.tests.views.test_ProfileListView.ProfilesListViewTests.test_view_get_context_data__should_return_correct_context /home/kk/Documents/Github/Phonotheque
Testing started at 15:54 ...
Found 1 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/views/generic/list.py:91: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class 'Phonotheque.accounts_app.models.Profile'> QuerySet.
return self.paginator_class(
Destroying test database for alias 'default'...
Error
Traceback (most recent call last):
File "/home/kk/Documents/Github/Phonotheque/Phonotheque/accounts_app/views.py", line 138, in get_context_data
context['current_profile'] = Profile.objects.get(pk=self.request.user.pk)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/db/models/query.py", line 496, in get
raise self.model.DoesNotExist(
Phonotheque.accounts_app.models.Profile.DoesNotExist: Profile matching query does not exist.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/kk/Documents/Github/Phonotheque/Phonotheque/accounts_app/tests/views/test_ProfileListView.py", line 65, in test_view_get_context_data__should_return_correct_context
response = self.client.get('/accounts/profiles/')
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/test/client.py", line 836, in get
response = super().get(path, data=data, secure=secure, **extra)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/test/client.py", line 424, in get
return self.generic(
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/test/client.py", line 541, in generic
return self.request(**r)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/test/client.py", line 810, in request
self.check_exception(response)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/test/client.py", line 663, in check_exception
raise exc_value
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 119, in dispatch
return handler(request, *args, **kwargs)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/views/generic/list.py", line 174, in get
context = self.get_context_data()
File "/home/kk/Documents/Github/Phonotheque/Phonotheque/accounts_app/views.py", line 140, in get_context_data
Profile.objects.create(user=self.request.user)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/db/models/query.py", line 512, in create
obj = self.model(**kwargs)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/db/models/base.py", line 541, in __init__
_setattr(self, field.name, rel_obj)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 338, in __set__
super().__set__(instance, value)
File "/home/kk/Documents/Github/Phonotheque/venv/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 235, in __set__
raise ValueError(
ValueError: Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x7f682f11e220>>": "Profile.user" must be a "User" instance.
Process finished with exit code 1
How do I simulate creation of multiple users/profiles, logging in of one of them and obtaining the relevant data?
Thanks a lot in advance.
It was quite a specific question and I very much doubt anyone ever will be looking at this answer but just in case:
def test_view_get_context_data__with__logged_in_user_should_return_correct_context(self):
user_data = {'username': 'BayHuy', 'password': '11111111', }
new_user = User.objects.create_user(**user_data)
new_profile = Profile.objects.create(user=new_user)
self.assertEqual(len(User.objects.all()), 1)
self.assertEqual(new_profile.user_id, new_user.pk)
self.assertEqual(len(Profile.objects.all()), 1)
self.client.login(**user_data)
response = self.client.get(reverse('profiles-list'))
self.assertEqual(
new_profile,
response.context_data['current_profile'])
self.assertEqual(
new_profile, response.context_data['current_profile'])
self.assertEqual(len(response.context_data['profile_list']), 1)
I'm using django-revproxy and Django REST Framework in my project. And I'm exposing an API where users get analytics about their chatbots, and it works as the following:
The user send requests the analytics from the Django project
Django project, checks if the user is authenticated and owns that chatbot
if True it contacts another external service.
My urls.py:
# urls.py
urlpatterns = (
url(r'^analytics/(?P<path>.*)$', api.AnalyticsFunctionsProxyView.as_view()),
)
And in my view:
# views.py
from rest_framework.authentication import TokenAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated
from revproxy.views import ProxyView
from .permissions import HasChatBotPermission
...
class AnalyticsFunctionsProxyView(ProxyView):
upstream = settings.ANALYTICS_FAAS_URL
def parse_body(self, request):
if isinstance(request, rest_framework.request.Request):
return request.data
return super(AnalyticsFunctionsProxyView, self).parse_body(request)
#classmethod
def as_view(cls, *args, **kwargs):
view = super(AnalyticsFunctionsProxyView, cls).as_view(*args, **kwargs)
view = permission_classes((IsAuthenticated, HasChatBotPermission,))(view)
view = authentication_classes([TokenAuthentication, JSONWebTokenAuthentication])(view)
view = api_view(['GET', 'POST'])(view)
return view
And my HasChatBotPermission permissions
#permissions.py
class HasChatBotPermission(permissions.BasePermission):
def has_permission(self, request, view):
try:
bot_name = request.data.get('name')
user = request.user
self.message = 'Permission denied for {}'.format(name)
return ChatBot.objects.filter(user=user, project_name=project_id).exists()
except Exception:
self.message = 'Permission denied, no project_id was defined!'
return False
When the view is called it raises this exception:
Traceback (most recent call last):
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/rest_framework/request.py", line 379, in __getattribute__
return super(Request, self).__getattribute__(attr)
AttributeError: 'Request' object has no attribute 'body'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 42, in inner
response = get_response(request)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/fcmam5/anaconda3/lib/python3.6/contextlib.py", line 52, in inner
return func(*args, **kwds)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/rest_framework/views.py", line 477, in dispatch
response = self.handle_exception(exc)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/rest_framework/views.py", line 437, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/rest_framework/views.py", line 474, in dispatch
response = handler(request, *args, **kwargs)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/rest_framework/decorators.py", line 52, in handler
return func(*args, **kwargs)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/revproxy/views.py", line 204, in dispatch
proxy_response = self._created_proxy_response(request, path)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/revproxy/views.py", line 139, in _created_proxy_response
request_payload = request.body
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/rest_framework/request.py", line 383, in __getattribute__
return getattr(self._request, attr)
File "/home/fcmam5/dela3a/env/lib/python3.6/site-packages/django/http/request.py", line 264, in body
raise RawPostDataException("You cannot access body after reading from request's data stream")
django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
The issue is caused by this line bot_name = request.data.get('name') in my permissions.py, when I pass a string directly it passes without any problems.
My question is:
How can I access the request body without having this error? Why I'm having this error?
Is there a better solution for checking the user permission with Django revproxy.
This is my first question in Stackoverflow, sorry if my question is not clea, and for my poor English :)
You're having this error because django-revproxy attempts to read the raw request body so it can create a proxy request to the upstream server.
However, with Django's (and WSGI's, and buffering) semantics, this isn't possible once you've accessed the request body as anything but a raw stream, which you do when you request.data.get('name'). This parses the request body as JSON, HTTP multipart, whatever, depending on DRF's request negotiation configuration, and consumes the stream.
There are two ways you could get around this, as far as I see:
pass bot_name somewhere else than the body; a query string parameter, an HTTP header, part of the URL, for instance, so you don't need to access the body, or
make the backend request yourself using requests instead of reverse-proxying (which is basically the same thing, but with added magic to try and copy the request through as-is).
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.user
list_.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='a#b.com')
self.client.force_login(user)
self.client.post('/lists/new', data={'text': 'new item'})
mock_list = mockListClass.return_value
self.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 inner
response = get_response(request)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = 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_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/mnt/BAC4BB93C4BB4FFD/codes/tdd/superlists/lists/views.py", line 36, in new_list
return redirect(list_)
File "/home/sjsakib/.virtualenvs/superlists/lib/python3.6/site-packages/django/shortcuts.py", line 58, in redirect
return 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_uri
return quote(iri, safe="/#%[]=:;$&()+,!?*#'~")
File "/usr/local/lib/python3.6/urllib/parse.py", line 787, in quote
return quote_from_bytes(string, safe)
File "/usr/local/lib/python3.6/urllib/parse.py", line 812, in quote_from_bytes
raise 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
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.user
list_.save()
form.save(for_list=list_)
return redirect(str(list_.get_absolute_url()))
else:
return render(request, 'home.html', {"form": form})
Please see my answer here which only changes the testing code, while resulting in the desired production code.
In short,
Patch the redirect
#patch('app_name.views.redirect')
Pass mock_redirect as argument
def test_new_list_redirects_view(self, mock_redirect):
Check that the response is equal to the return_value of the mock_redirect
response = new_list(self.request)
self.assertEqual(response, mock_redirect.return_value)
Per one of the comments: I did change my code to:
providers = Provider.objects.all()
context = { 'providers':providers}
I know it didn't make a difference but figured I would try it anyway cause stranger things have happened. I am worried the error is within the module itself running on my version of django here.
I did see the other answers on this, and it confused me because I am just using what was documented here:
https://spapas.github.io/2015/11/27/pdf-in-django/#django-integration
for getting the django_xhtml2pdf stuff to work. My view is as such:
def providers_plain_old_view(request):
resp = HttpResponse(content_type='application/pdf')
context = {
'providers': Provider.objects.all()
}
result = generate_pdf('ipaswdb/provider/providers_plain_old_view.html', file_object=resp, context=context)
return result
Which I know now is bad in django 1.11.14 I am using, but no idea how to fix the error:
Traceback (most recent call last):
File "D:\Python27\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "D:\Python27\lib\site-packages\django\core\handlers\base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "D:\Python27\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "D:\Python27\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\Programming\web\ipa_django\mysite\ipaswdb\views.py", line 312, in providers_plain_old_view
result = generate_pdf('ipaswdb/provider/providers_plain_old_view.html', file_object=resp, context=context)
File "D:\Python27\lib\site-packages\django_xhtml2pdf\utils.py", line 62, in generate_pdf
generate_pdf_template_object(tmpl, file_object, context)
File "D:\Python27\lib\site-packages\django_xhtml2pdf\utils.py", line 39, in generate_pdf_template_object
html = template_object.render(Context(context))
File "D:\Python27\lib\site-packages\django\template\backends\django.py", line 64, in render
context = make_context(context, request, autoescape=self.backend.engine.autoescape)
File "D:\Python27\lib\site-packages\django\template\context.py", line 287, in make_context
raise TypeError('context must be a dict rather than %s.' % context.__class__.__name__)
TypeError: context must be a dict rather than Context.
"GET /ipaswdb/provider_roster/ HTTP/1.1" 500 86485
I mean it wants me to call the generate_pdf function a different way in the latest django version?
The main issue lies in the line
File "D:\Python27\lib\site-packages\django_xhtml2pdf\utils.py", line 39, in generate_pdf_template_object
html = template_object.render(Context(context))
in the error output. This is an issue the django-xhtml2pdf package not being up to date for 1.11. The call to render has changed from
html = template_object.render(Context(context))
to
html = template_object.render(context)
according to the upgrading to 1.11 notes https://docs.djangoproject.com/en/1.11/ref/templates/upgrading/
django.template.loader section.
You can either wait for them to fix it, by submitting a bug report or implement the functionality the package provides in your views.py