i have problem editing my queryset in Django REST framwork.
Basically i need to filter my query and return single one, so my DRF view look like this:
class MyModelViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
def get_queryset(self):
start = self.kwargs['start']
end = self.kwargs['end']
qs, created = MyModel.objects.get_or_create(start=start, end=end)
return qs
So i return single model instance, but when i try to get access true the DRF web interface i get an error 'MyModel' object has no attribute 'model'
Traceback:
File "/Users/stay-wide-awake/code/env/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/stay-wide-awake/code/env/lib/python3.4/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "/Users/stay-wide-awake/code/env/lib/python3.4/site-packages/rest_framework/viewsets.py" in view
85. return self.dispatch(request, *args, **kwargs)
File "/Users/stay-wide-awake/code/env/lib/python3.4/site-packages/rest_framework/views.py" in dispatch
456. response = self.handle_exception(exc)
File "/Users/stay-wide-awake/code/env/lib/python3.4/site-packages/rest_framework/views.py" in dispatch
444. self.initial(request, *args, **kwargs)
File "/Users/stay-wide-awake/code/env/lib/python3.4/site-packages/rest_framework/views.py" in initial
359. self.check_permissions(request)
File "/Users/stay-wide-awake/code/env/lib/python3.4/site-packages/rest_framework/views.py" in check_permissions
304. if not permission.has_permission(request, self):
File "/Users/stay-wide-awake/code/asp/src/apps/api2/permission.py" in has_permission
34. perms = self.get_required_permissions(request.method, queryset.model)
Exception Type: AttributeError at /api/v2/geo/36.606111,-118.062778|36.578581,-120.291994/
Exception Value: 'MyModel' object has no attribute 'model'
Router and all other parts is OK (tested via prints :))
Will be grateful for any hints.
The object received via MyModel.objects.get_or_create(start=start, end=end) is not a queryset hence you are getting this error.
Django's get_or_create() returns a tuple of (object, created) where object is the retrieved or created object and created is a boolean specifying whether a new object was created.
In your get_queryset() method, you are setting queryset qs to this received object when infact its a model object.
get_queryset() should return a queryset and not a model object which you are doing.
You can do something like:
def get_queryset(self):
start = self.kwargs['start']
end = self.kwargs['end']
mymodel_obj, created = MyModel.objects.get_or_create(start=start, end=end)
return MyModel.objects.filter(id=mymodel_obj.id) # returns a queryset now
Related
I am on django 4.0.4 and have a benign but annoying problem with the above error code.
Previous responses to similar questions don't help me.
When I backspace, (an incovenience a user may not think of) everything has actually gone well, the list and detail views are correctly updated.
The create form is however as it was as if it was not saved, and the view doesn't change to the detail view as suggested by the get_absolute_url, which may lead one to process it again.
The code from previous models is exactly the same where it matters. An example is the TaskCreate view which is giving the problem and the ObjectiveCreate view just before it which works as expected.
In the views, I find the user and his/her entity (even though there is one entity), and process that user as a supervisor1 and also automatically process the entity.
The error finds fault with the TaskCreate view's "return super().form_valid(form)" but not with that in the ObjectiveCreate view.
Here is the code for the two views
class ObjectiveCreate(LoginRequiredMixin, CreateView):
model = Objective
form_class = ObjectiveCreateForm
template_name = "internalcontrol/objective_create_form.html"
def form_valid(self, form):
user = self.request.user
profile = Profile.objects.get(user=user)
entity = profile.entity
new_profile = Profile.objects.get(user=user, entity=entity)
form.instance.supervisor1 = new_profile
form.instance.entity = entity
return super().form_valid(form)
def get_form_kwargs(self):
kwargs = super(ObjectiveCreate, self).get_form_kwargs()
kwargs["request"] = self.request
return kwargs
class TaskCreate(LoginRequiredMixin, CreateView):
model = Task
form_class = TaskCreateForm
template_name = "internalcontrol/task_create_form.html"
def form_valid(self, form):
user = self.request.user
profile = Profile.objects.get(user=user)
entity = profile.entity
new_profile = Profile.objects.get(user=user, entity=entity)
form.instance.supervisor1 = new_profile
form.instance.entity = entity
return super().form_valid(form)
def get_form_kwargs(self):
kwargs = super(TaskCreate, self).get_form_kwargs()
kwargs["request"] = self.request
return kwargs
The respective get_absolute_url for both models are:
def get_absolute_url(self):
return reverse(
"internalcontrol:objective_detail",
kwargs={"pk": self.pk},
)
and
def get_absolute_url(self):
return (
reverse("internalcontrol:task_detail", kwargs={"pk": self.pk}),
)
The traceback is as follows:
Internal Server Error: /task_create/
Traceback (most recent call last):
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\views\generic\base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\contrib\auth\mixins.py", line 73, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\views\generic\base.py", line 119, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\views\generic\edit.py", line 184, in post
return super().post(request, *args, **kwargs)
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\views\generic\edit.py", line 153, in post
return self.form_valid(form)
File "C:\Users\User\Documents\django projects\nguyena\internalcontrol\views.py", line 231, in form_valid
return super().form_valid(form)
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\views\generic\edit.py", line 136, in form_valid
return super().form_valid(form)
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\views\generic\edit.py", line 65, in form_valid
return HttpResponseRedirect(self.get_success_url())
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\http\response.py", line 538, in __init__
self["Location"] = iri_to_uri(redirect_to)
File "C:\Users\User\.virtualenvs\nguyena-QPBkFrkQ\lib\site-packages\django\utils\encoding.py", line 139, in iri_to_uri
return quote(iri, safe="/#%[]=:;$&()+,!?*#'~")
File "c:\users\user\appdata\local\programs\python\python39\lib\urllib\parse.py", line 871, in quote
return quote_from_bytes(string, safe)
File "c:\users\user\appdata\local\programs\python\python39\lib\urllib\parse.py", line 896, in quote_from_bytes
raise TypeError("quote_from_bytes() expected bytes")
TypeError: quote_from_bytes() expected bytes
[18/Apr/2022 17:08:13] "POST /task_create/ HTTP/1.1" 500 125026
I think the problem is the final address to which the user should be redirected.
To solve this problem, first edit the get_absolute_url function to return a string, not a tuple.
If it still does not work, try adding a success_url to the view with reverse_lazy
I'm trying to perform a bit of complicated query in my rest api view so I can order my contacts in the right order, now as e4c5 suggested in my previous question I could do this Case annotation and build my custom annotation with CASE/WHEN and then use that in annotation in the order by, but now I'm getting ValueError at /api/sales/lead_contact/
The annotation 'status' conflicts with a field on the model so this is the custom annotation I'm trying to build so I can properly order contacts, one note is that I'm preforming this in rest view:
class LeadContactViewSet(viewsets.ModelViewSet):
def get_queryset(self):
filter_date = self.request.query_params.get('filter_date', None)
case_sql = LeadContact.objects.annotate(
status=Case(
When(status=LeadContactConstants.STATUS_CLIENT, then=Value('1')),
When(status=LeadContactConstants.STATUS_QUALIFIED, then=Value('2')),
When(status=LeadContactConstants.STATUS_CONTACTED, then=Value('3')),
When(status=LeadContactConstants.STATUS_PRISTINE, then=Value('4')),
default=Value('1'),
output_field=CharField(),
)
).values_list('status')
if filter_date is not None:
queryset = queryset.filter(next_action_date=filter_date).extra(select={'status': case_sql},
order_by=['status'])
return queryset
Model fields:
class LeadContact(models.Model):
status = models.CharField(max_length=10,
choices=LeadContactConstants.STATUSES, default=LeadContactConstants.STATUS_PRISTINE)
and the choices for this field:
class LeadContactConstants(object):
STATUS_PRISTINE = "PRISTINE"
STATUS_CONTACTED = "CONTACTED"
STATUS_QUALIFIED = "QUALIFIED"
STATUS_CLIENT = "CLIENT"
STATUSES = ((STATUS_PRISTINE, "Virgin"),
(STATUS_CONTACTED, "Contacted"),
(STATUS_QUALIFIED, "Qualified"),
(STATUS_CLIENT, "Client"))
Serializer class:
class LeadContactSerializer(serializers.ModelSerializer):
account_handler = AccountHandlerSerializer()
next_action_date = serializers.DateTimeField(format=settings.CUSTOM_DATE_FORMAT_NO_TIME)
absolute_url = serializers.URLField(source='get_absolute_url')
class Meta:
model = LeadContact
fields = (
'pk', 'organization_name', 'sub_organization_name', 'serial_number', 'account_handler', 'status_text',
'first_name', 'last_name', 'next_action_date', 'absolute_url', 'status_display_class'
)
depth = 1
Full Stack Trace:
Traceback:
File "/home/vagrant/virtualenv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vagrant/virtualenv/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "/home/vagrant/virtualenv/local/lib/python2.7/site-packages/rest_framework/viewsets.py" in view
87. return self.dispatch(request, *args, **kwargs)
File "/home/vagrant/virtualenv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
466. response = self.handle_exception(exc)
File "/home/vagrant/virtualenv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
463. response = handler(request, *args, **kwargs)
File "/home/vagrant/virtualenv/local/lib/python2.7/site-packages/rest_framework/mixins.py" in list
40. queryset = self.filter_queryset(self.get_queryset())
File "/home/vagrant/vincluos/VincluCMSProject/vinclucms_sales/restapi/views/lead_contact_viewset.py" in get_queryset
29. output_field=CharField(),
File "/home/vagrant/virtualenv/local/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
127. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/vagrant/virtualenv/local/lib/python2.7/site-packages/django/db/models/query.py" in annotate
793. "the model." % alias)
Exception Type: ValueError at /api/sales/lead_contact/
Exception Value: The annotation 'status' conflicts with a field on the model.
As you can read the error message "'status' conflicts with a field on the model",
here the error is telling you that LeadContact model already has a field status (you can see it on your model definition of LeadContact)
that's why you're not able to annotate.
Basically annotate tries to add a field to your queryset result in your case it is status as you have a model LeadContact with status field because of which you're not able to annotate.
The Solution is you have to the field name other then status and choices.
hope this helps.
I am using Django tabination to display several tabs using class based views. All classes used to display tabs inherit from MainNavigationBaseTab class:
class MainNavigationBaseTab(TabView):
"""Base class for all main navigation tabs."""
tab_group = 'main_navigation'
tab_classes = ['main-navigation-tab']
def get_context_data(self, **kwargs):
context = super(MainNavigationBaseTab, self).get_context_data(**kwargs)
context['main'] = 'maintenance'
return context
#property
def tab_classes(self):
"""If user is logged in, set ``logged_in_only`` class."""
classes = super(MainNavigationBaseTab, self).tab_classes[:]
if self.current_tab.request.user.is_authenticated():
classes += ['logged_in_only']
return classes
In one of the tabs I want to display a list of contacts derived from ListView class:
class ListContactView(ListView):
model = Contact
template_name = 'main_tab.html'
My approach was to derive the MainTab class from both MainNavigationBaseTab and ListContactView:
class MainTab(ListContactView, MainNavigationBaseTab):
_is_tab = True
tab_id = 'main'
tab_label = _('Main')
template_name = 'main_tab.html'
however the problem I have with this approach is that get_context_data() method is called on wrong class and object_list is not found in context when I try to display the tab. Below is the full error message I am getting:
Traceback:
File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py"
in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py"
in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.7/site-packages/django/views/generic/base.py"
in view
68. return self.dispatch(request, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/django/views/generic/base.py"
in dispatch
88. return handler(request, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/django/views/generic/base.py"
in get
157. context = self.get_context_data(**kwargs)
File "/home/.../views.py" in get_context_data
27. context = super(PatientListView, self).get_context_data(**kwargs)
File "/home/.../views.py" in get_context_data
37. context = super(MainNavigationBaseTab, self).get_context_data(**kwargs)
File "/usr/lib/python2.7/site-packages/tabination/views.py" in
get_context_data
145. context = super(TabView, self).get_context_data(**kwargs)
File "/usr/lib/python2.7/site-packages/django/views/generic/list.py"
in get_context_data
130. queryset = kwargs.pop('object_list', self.object_list)
Exception Type: AttributeError at /mainview/ Exception Value:
'MainTab' object has no attribute 'object_list'
Could someone tell me how to display the list of contacts using a model stored in a database with Django tabination ?
thanks
Bogdan
I'm getting a strange 500 error when issuing an OPTION request to an endpoint in my API built with Django Rest Framework. GET, POST, PUT all work fine and DELETE is not allowed.
When issuing an OPTION request to the endpoint, I get the following error and traceback:
Traceback:
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/django/views/decorators/csrf.py" in wrapped_view
57. return view_func(*args, **kwargs)
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/viewsets.py" in view
85. return self.dispatch(request, *args, **kwargs)
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/views.py" in dispatch
452. response = self.handle_exception(exc)
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/views.py" in dispatch
449. response = handler(request, *args, **kwargs)
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/views.py" in options
463. data = self.metadata_class().determine_metadata(request, self)
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/metadata.py" in determine_metadata
63. actions = self.determine_actions(request, view)
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/metadata.py" in determine_actions
89. actions[method] = self.get_serializer_info(serializer)
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/metadata.py" in get_serializer_info
106. for field_name, field in serializer.fields.items()
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/metadata.py" in <listcomp>
106. for field_name, field in serializer.fields.items()
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/metadata.py" in get_field_info
129. if hasattr(field, 'choices'):
File "/Users/awwester/Sites/django/rlg/lib/python3.4/site-packages/rest_framework/relations.py" in choices
382. for item in iterable
Exception Type: TypeError at /v1/powerChatSessions
Exception Value: 'NoneType' object is not iterable
Here is the model, serializer, and view:
# models.py - error happens when issuing OPTIONS /powerChatSession
class VideoConversation(models.Model):
"""
Capture data about a video chat session
SO note: this is inherited by other classes besides PowerChat
"""
created = models.DateTimeField(auto_now_add=True)
end = models.DateTimeField(null=True, blank=True)
users = models.ManyToManyField(User)
class PowerChat(VideoConversation):
"""
power chat session
"""
start = models.DateTimeField(null=True, blank=True)
extended = models.BooleanField(default=False)
active = models.BooleanField(default=False)
# serializers.py
class PowerChatSerializer(serializers.ModelSerializer):
class Meta:
model = PowerChat
read_only_fields = ('users', 'start', 'extended',)
# views.py
class PowerChatViewSet(ModelViewSet):
queryset = PowerChat.objects.all()
permission_classes = (PowerChatPermission,)
serializer_class = PowerChatSerializer
resource_name = "powerChatSession"
Any ideas why this is happening? It has something to do with the users field, and it seems that it could be a bug with Django Rest Framework? It's checking if the field has the choices kwarg, which it doesn't, but apparently DRF thinks it does?
I think this issue was addressed by:
https://github.com/tomchristie/django-rest-framework/issues/3115
The gist is that "At the moment, self.action is None in viewsets if I get an OPTIONS request."
This issue ceased for me after I upgraded to djangorestframework-3.2.3
After using HttpResponseRedirect and reverse to redirect to another view, I am getting a ValueError. This is the view that processes a posted form (the form uses a ModelChoiceField to get a dropdown set of options from my Make model:
def browse(request):
thing_list = Thing.objects.all()
if request.method == 'POST':
form = BrowseForm(request.POST)
if form.is_valid():
make = form.cleaned_data['make']
return HttpResponseRedirect(reverse('browse_makes', kwargs={'make':make}))
else:
form = BrowseForm()
return render(request, 'browse.html', {'form':form, 'thing_list':thing_list})
.. then redirects to next view adding make as a kwarg to use to filter the next queryset:
def makes(request, make):
thing_list = Thing.objects.filter(make=make)
return render(request, 'browse-makes.html', {'thing_list':thing_list})
urls:
url(r'^browse/$', 'myapp.views.browse.browse', name='browse'),
url(r'^browse/(?P<make>[\w-]+)/$', 'myapp.views.browse.makes', name='browse_makes'),
Results in ValueError: invalid literal for int() with base 10: 'Samsung' when selecting an option from the form. After googling, still not sure how to solve this.. Thanks for any ideas how to solve this error!
EDIT:
abbreviated model:
class Thing(models.Model):
user = models.ForeignKey(User)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
slug = models.SlugField()
make = models.ForeignKey(Make)
Traceback:
Traceback: File "/lib/python2.7/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs) File "/myproject/myapp/views/browse.py" in makes
21. thing_list = Thing.objects.filter(make=make) File "/lib/python2.7/django/db/models/manager.py" in filter
143. return self.get_query_set().filter(*args, **kwargs) File "/lib/python2.7/django/db/models/query.py" in filter
624. return self._filter_or_exclude(False, *args, **kwargs) File "/lib/python2.7/django/db/models/query.py" in _filter_or_exclude
642. clone.query.add_q(Q(*args, **kwargs)) File "/lib/python2.7/django/db/models/sql/query.py" in add_q
1250. can_reuse=used_aliases, force_having=force_having) File "/lib/python2.7/django/db/models/sql/query.py" in add_filter
1185. connector) File "/lib/python2.7/django/db/models/sql/where.py" in add
69. value = obj.prepare(lookup_type, value) File "/lib/python2.7/django/db/models/sql/where.py" in prepare
320. return self.field.get_prep_lookup(lookup_type, value) File "/lib/python2.7/django/db/models/fields/related.py" in get_prep_lookup
137. return self._pk_trace(value, 'get_prep_lookup', lookup_type) File "/lib/python2.7/django/db/models/fields/related.py" in _pk_trace
210. v = getattr(field, prep_func)(lookup_type, v, **kwargs) File "/lib/python2.7/django/db/models/fields/__init__.py" in get_prep_lookup
310. return self.get_prep_value(value) File "/lib/python2.7/django/db/models/fields/__init__.py" in get_prep_value
537. return int(value)
Exception Type: ValueError at /browse/Samsung/ Exception Value: invalid literal for int() with base 10: 'Samsung'
If you post your Make model, I can give a complete answer. But in general you are referencing the make foreign key directly - which is an int (the Make ID). You are comparing this int to the string 'samsung' at make=make causing the error.
Depending on what string fields your Make model has, you need to reference one of those fields. For instance, if Make had a name field that accepted strings:
thing_list = Thing.objects.filter(make__name=make)
Otherwise, you need to pass the make ID instead of 'samsung'