Django access request.user in class based view - python

I'm currently working on the following issue: The user can access the page test.com/BlogPostTitle. Where BlogPostTitle is a slug. If a Blog post with the fitting title exists, Django should render the DetailView of said blog post. If it doesn't exist, Django should render a form to create a blog post.
This works so far:
class EntryDetail(DetailView): # Displays blog entry, if it exists
model = Blog
slug_field = 'title'
template_name = 'app/entry.html'
class EntryForm(FormView): # Displays form, if entry 404s
template_name = 'app/create.html'
form_class = EntryForm
success_url = '/'
def form_valid(self, form):
form.save()
return super(EntryForm, self).form_valid(form)
class EntryDisplay(View):
def get(self, request, *args, **kwargs):
try:
view = EntryDetail.as_view()
return view(request, *args, **kwargs)
except Http404:
if check_user_editor(self.request.user) == True: # Fails here
view = EntryForm.as_view()
return view(request, *args, **kwargs)
else:
pass
Now, only users who are in the group "editor" should be able to see the form/create a post:
def check_user_editor(user):
if user:
return user.groups.filter(name="editor").exists() # Returns true, if user in editor group
else:
return Falseâ‹…
As you can see, I've implemented the function in the EntryDisplay, however, Django errors 'User' object is not iterable.
I'm guessing I've to work with SingleObjectMixin, but I haven't quite understood the docs on that.
Any help would be much appreciated.
Full traceback:
Traceback:
File "/home/django/local/lib/python3.4/site-packages/django/views/generic/detail.py" in get_object
53. obj = queryset.get()
File "/home/django/local/lib/python3.4/site-packages/django/db/models/query.py" in get
385. self.model._meta.object_name
During handling of the above exception (Blog matching query does not exist.), another exception occurred:
File "/home/django/mediwiki/mediwiki/views.py" in get
68. return view(request, *args, **kwargs)
File "/home/django/local/lib/python3.4/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/home/django/local/lib/python3.4/site-packages/django/views/generic/base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "/home/django/local/lib/python3.4/site-packages/django/views/generic/detail.py" in get
115. self.object = self.get_object()
File "/home/django/local/lib/python3.4/site-packages/django/views/generic/detail.py" in get_object
56. {'verbose_name': queryset.model._meta.verbose_name})
During handling of the above exception (No blog found matching the query), another exception occurred:
File "/home/django/local/lib/python3.4/site-packages/django/core/handlers/exception.py" in inner
39. response = get_response(request)
File "/home/django/local/lib/python3.4/site-packages/django/core/handlers/base.py" in _legacy_get_response
249. response = self._get_response(request)
File "/home/django/local/lib/python3.4/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/home/django/local/lib/python3.4/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/django/local/lib/python3.4/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/home/django/local/lib/python3.4/site-packages/django/views/generic/base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "/home/django/mediwiki/mediwiki/views.py" in get
74. view = HttpResponse(request.user)
File "/home/django/local/lib/python3.4/site-packages/django/http/response.py" in __init__
293. self.content = content
File "/home/django/local/lib/python3.4/site-packages/django/http/response.py" in content
319. content = b''.join(self.make_bytes(chunk) for chunk in value)
File "/home/django/local/lib/python3.4/site-packages/django/utils/functional.py" in inner
235. return func(self._wrapped, *args)
Exception Type: TypeError at /test
Exception Value: 'User' object is not iterable

Your error is in line 74 in mediwiki.views:
view = HttpResponse(request.user)
HttpResponse expects a string or an iterable. Since request.user is not a string, it tries to use it as an iterable, which fails.
I can't say much without the actual code. If in fact you want to send just a string representation of the user as the response, you need to cast is to a string:
view = HttpResponse(str(request.user))

Is the error occurred at template rendering? If so I wonder you've make iter over attributes on single User object. I think you may need user.values().
BTW, check_user_editor should be simpler:
def check_user_editor(user):
return user.groups.filter(name="editor").exists()

Related

DRF request handler is throwing exception: retrieve() got an unexpected keyword argument 'pk'

I'm trying to retrieve a model instance in Django Rest Framework 3.6.3 at /path/to/API/widget/1/, 1 being the primary key of the widget. It's giving me:
retrieve() got an unexpected keyword argument 'pk'
From the trace I think I'm doing something to cause dispatch to throw an exception when instantiating the handler (from views.py, source here). I don't understand what I'm doing wrong through when I examine the source. Here's the trace:
Traceback:
File "/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/lib/python3.5/site-packages/django/core/handlers/base.py" in _legacy_get_response
249. response = self._get_response(request)
File "/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/lib/python3.5/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "/lib/python3.5/site-packages/rest_framework/viewsets.py" in view
86. return self.dispatch(request, *args, **kwargs)
File "/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
489. response = self.handle_exception(exc)
File "/lib/python3.5/site-packages/rest_framework/views.py" in handle_exception
449. self.raise_uncaught_exception(exc)
File "/lib/python3.5/site-packages/rest_framework/views.py" in dispatch
486. response = handler(request, *args, **kwargs)
Exception Type: TypeError at /path/to/API/widget/1/
Exception Value: retrieve() got an unexpected keyword argument 'pk'
Here's the view from the ViewSet:
def retrieve(self, request, some_lookup_field=None):
instance = self.get_object(pk) # handle multi-tenant access control
if not instance:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = self.get_serializer(instance) # from the class's `serializer_cass` attribute
return Response(serializer.data)
As you see in your stacktrace, the error is:
retrieve() got an unexpected keyword argument 'pk'.
Look closely in your retrieve() function:
def retrieve(self, request, some_lookup_field=None):
# ____________________________^
instance = self.get_object(pk) # handle multi-tenant access control
# _________________________^
...
You are taking some_lookup_field as a parameter and not pk, that you use below in self.get_object(pk). Try to rename some_lookup_field to pk.
This error might because you put wrong urls in your url.py. I've had the same problem in my project

Where has cleaned_data vanished in Django 1.11?

I have created an inlineformset_factory as below :
formset = inlineformset_factory(Author, Book, form=BookForm,
formset=BaseBookFormSet,
can_order=False, can_delete=True,
extra=1, fields=('id', name)
)
BookForm is as below:
class BookForm(forms.ModelForm):
name = forms.Charfield(required=True)
def __init__(self, *args, **kwargs):
super(BookForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout(
Div(
Field("id", type="hidden"),
Field("name"),
Field("DELETE")
)
)
class Meta:
model = Book
fields = ('id', 'name')
def clean_name(self):
book_name = self.cleaned_data['name']
try:
book = Book.objects.get(name=book_name)
return book
except:
return book_name
def clean(self):
cleaned_data = super(BookForm, self).clean()
... other operations on cleaned_data ...
def has_changed(self):
changed = super(BookForm, self).has_changed()
cleaned_data = self.clean()
... other code here ...
This is throwing an error on submitting the form :
Exception Type: AttributeError
Exception Value: 'BookForm' object has no attribute 'cleaned_data'
when formset.is_valid() is called in views.py. Traceback first shows the line in has_changed where the self.clean is being called, and then the line in clean() where the super clean is being called.
This used to work fine in django 1.10.
When I tried printing dir(self) in Django 1.10 it does show 'cleaned_data' as one of the attributes where as in Django 1.11 it does not.
Where has the 'cleaned_data' vanished in Django 1.11?
EDIT: Adding traceback:
Traceback (most recent call last):
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/views/generic/base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "/vagrant/test_os/inventory/views.py", line 297, in post
if formset.is_valid():
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/formsets.py", line 321, in is_valid
self.errors
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/formsets.py", line 295, in errors
self.full_clean()
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/formsets.py", line 345, in full_clean
if not form.has_changed():
File "/vagrant/test_os/inventory/forms.py", line 220, in has_changed
cleaned_data = self.clean()
File "/vagrant/test_os/inventory/forms.py", line 177, in clean
cleaned_data = super(BookForm, self).clean()
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/models.py", line 344, in clean
return self.cleaned_data
AttributeError: 'BookForm' object has no attribute 'cleaned_data'
Formsets were fixed in 1.11 (in #26844) to ignore empty forms when validating the minimum number of forms. As a side-effect, formsets now call form.has_changed() on each form before validating the form. Django expects form.has_changed() to be safe to call before the form is validated, and the default implementation is indeed safe to call.
You have overridden form.has_changed() to call self.clean(), which now happens before the form is validated. Since form.clean() requires that the form is validated, this fails.
Since form.full_clean() actually calls self.has_changed(), you can't simply validate the form from within form.has_changed(). You don't show what you do in has_changed(), but it would most likely be a good idea to put this code elsewhere.

View to use external URL

I want to access ElasticSearch securely via a Django URL. From this request, I will lookup the user's token to get their primary key. Then I will only show ES results that match.
For now, I just want to connect to my ElasticSearch URL. It would kind of work like a "proxy".
Anyway, the following returns the bottom traceback. How do I set it up correctly? Do I need a serialiser
views.py
from django.http import HttpResponseRedirect
class ElasticViewSet(viewsets.ModelViewSet):
def my_view(request):
if True:
return HttpResponseRedirect('http://localhost:9200/_seach')
urls.py
router.register(r'elastic', ElasticViewSet, base_name='Elastic')
Traceback
Traceback:
File "/Users/mac1/Dev/A51/Backend/NewDJ/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/Users/mac1/Dev/A51/Backend/NewDJ/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/mac1/Dev/A51/Backend/NewDJ/venv/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "/Users/mac1/Dev/A51/Backend/NewDJ/venv/lib/python2.7/site-packages/rest_framework/viewsets.py" in view
83. return self.dispatch(request, *args, **kwargs)
File "/Users/mac1/Dev/A51/Backend/NewDJ/venv/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
477. response = self.handle_exception(exc)
File "/Users/mac1/Dev/A51/Backend/NewDJ/venv/lib/python2.7/site-packages/rest_framework/views.py" in handle_exception
437. self.raise_uncaught_exception(exc)
File "/Users/mac1/Dev/A51/Backend/NewDJ/venv/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
474. response = handler(request, *args, **kwargs)
File "/Users/mac1/Dev/A51/Backend/NewDJ/venv/lib/python2.7/site-packages/rest_framework/mixins.py" in list
40. queryset = self.filter_queryset(self.get_queryset())
File "/Users/mac1/Dev/A51/Backend/NewDJ/venv/lib/python2.7/site-packages/rest_framework/generics.py" in get_queryset
67. % self.__class__.__name__
Exception Type: AssertionError at /****/elastic/
Exception Value: 'ElasticViewSet' should either include a `queryset` attribute, or override the `get_queryset()` method.
First thing first, you don't want a ModelViewSet as there's no Model. Just go for the regular ViewSet.
Second, please take some time to think about what you want to do and how you want it done. my_view is not a ViewSet regular action. Returning HttpResponseRedirect is not acting as a proxy.

MongoDBForm error "ValueError:A document class must be provided"

Hi i am creating a simple Sign Up form with django framework and mongodb. Following is my view:
class SignUpView(FormView):
template_name='MnCApp/signup.html'
form_class=EmployeeForm()
succes_url='/success/'
Following is my model:
class Employee(Document):
designation=StringField()
department=StringField()
emp_name=StringField(max_length=50)
password=StringField(max_length=10)
Following is my forms.py
class EmployeeForm(DocumentForm):
class meta:
desigs=(
('D','Director'),
('GM','General Manager'),
('AM','Assistant Manager'),
('A','Associates')
)
deptts=(
('HR','Human Resources'),
('IT','IT Support'),
('TT','Technical Team'),
('SM','Sales and Marketting'),
('SS','Support Staff')
)
document=Employee
fields='__all__'
widgets={
'designation':Select(choices=desigs),
'department':Select(choices=deptts)
}
Following is the traceback ValueError recieved on loading SignUpview
Traceback:
File "C:\Program Files\Python35\lib\site-packages\django\core\handlers\exception.py" in inner
39. response = get_response(request)
File "C:\Program Files\Python35\lib\site-packages\django\core\handlers\base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "C:\Program Files\Python35\lib\site-packages\django\core\handlers\base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Program Files\Python35\lib\site-packages\django\views\generic\base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "C:\Program Files\Python35\lib\site-packages\django\views\generic\base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "C:\Program Files\Python35\lib\site-packages\django\views\generic\edit.py" in get
174. return self.render_to_response(self.get_context_data())
File "C:\Program Files\Python35\lib\site-packages\django\views\generic\edit.py" in get_context_data
93. kwargs['form'] = self.get_form()
File "C:\Program Files\Python35\lib\site-packages\django\views\generic\edit.py" in get_form
45. return form_class(**self.get_form_kwargs())
File "C:\Program Files\Python35\lib\site-packages\mongodbforms\documents.py" in init
353. raise ValueError('A document class must be provided.')
Exception Type: ValueError at /signup/
Exception Value: A document class must be provided.
I am not able to find root of this problem. I am new to django and this is my first project. Also is their anyother way for creating model forms for mongo documents??
I suspect that your inner class should be called Meta, not meta.

AttributeError at /circular/1/detail/ 'CircularDetail' object has no attribute 'pk' in Django

class CircularDetail(DeleteView):
model = Circular
template_name = 'genre/circular_detail.html'
def get_context_data(self, **kwargs):
ctx = super(CircularDetail, self).get_context_data(**kwargs)
ctx['c'] = Circular.objects.get(pk=self.pk)
ctx['sittings'] = Sitting.objects.all()
ctx['ballot'] = Sitting.objects.all()
return ctx
Above view give me following errors:
Traceback:
File "/home/ohid/test_venv/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/home/ohid/test_venv/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/ohid/test_venv/lib/python3.5/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/home/ohid/test_venv/lib/python3.5/site-packages/django/views/generic/base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "/home/ohid/test_venv/lib/python3.5/site-packages/django/views/generic/detail.py" in get
118. context = self.get_context_data(object=self.object)
File "/home/ohid/test_venv/myapp/genre/views.py" in get_context_data
126. ctx['c'] = Circular.objects.get(pk=self.pk)
Exception Type: AttributeError at /circular/1/detail/
Exception Value: 'CircularDetail' object has no attribute 'pk'
I need your assistance to fix this issues.
URL parameters are passed via kwargs, so you can access it this way
self.kwargs.get("pk")
so change
ctx['c'] = Circular.objects.get(pk=self.pk)
to
ctx['c'] = Circular.objects.get(pk=self.kwargs.get("pk"))
First of all, fix your base class to DetailView (instead of DeleteView)
DetailView inherited from django.views.generic.detail.SingleObjectMixin (https://docs.djangoproject.com/en/1.10/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin) which expects primary key to be in slug parameter, so fix your URL regexp to
r'^circular/(?P<slug>[-\w]+)/detail$'
and access your object using self.object in view or just {{ object }} in template.

Categories