django rest framework OPTIONS 500 - django

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

Related

How to use ListSerializer with a ModelSerializer?

I am attempting to create a POST endpoint using DRF ListSerializer to create a list of LogLevel objects.
I have tried to serialize the foreign key using PrimaryKeyRelatedField without success.
models.py
relevant fields for LogLevel model. note foreign key to node model
#associated node
node = models.ForeignKey(Node, on_delete=models.DO_NOTHING,
related_name="log_levels")
#logger name
name = models.CharField(max_length=32, choices=LOGGERS)
# Current log level
level = models.IntegerField(default=INFO,
choices=LOG_LEVELS)
# Timestamps
created_datetime = models.DateTimeField(auto_now_add=True)
updated_datetime = models.DateTimeField(auto_now=True,
blank=True, null=True)
serializers.py
class LogLevelListSerializer(serializers.ListSerializer):
def create(self, validated_data):
log_levels = [LogLevel(**item) for item in validated_data]
levels = LogLevel.objects.bulk_create(log_levels)
return levels
class LogLevelCreateUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = LogLevel
fields = "__all__"
list_serializer_class = LogLevelListSerializer
LogLevel view
class LogLevelList(MethodSerializerMixin,
generics.ListCreateAPIView):
"""
Log Level list API Endpoint.
"""
method_serializer_classes = {
("POST",): LogLevelCreateUpdateSerializer
}
def get_queryset(self):
"""
Queryset to use for endpoint.
"""
return LogLevel.objects.all()
def get_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
# check if many is required
if "data" in kwargs:
data = kwargs["data"]
# check if many is required
if isinstance(data, list):
kwargs["many"] = True
return serializer_class(*args, **kwargs)
MethodSerializerMixin
from rest_framework import exceptions
class MethodSerializerMixin(object):
"""
Utility class to apply a different serializer class depending
on the request method.
For example:
method_serializer_classes = {
("GET", ): MyModelListViewSerializer,
("PUT", "PATCH"): MyModelCreateUpdateSerializer
}
"""
method_serializer_classes = None
def get_serializer_class(self):
assert self.method_serializer_classes is not None, (
f"Expected view {self.__class__.__name__} should contain "
f"method_serializer_classes to get right serializer class."
)
for methods, serializer_cls in self.method_serializer_classes.items():
if self.request.method in methods:
return serializer_cls
raise exceptions.MethodNotAllowed(self.request.method)
Im passing in a json list of simple objects in the request. node is the foreign key id:
[{
"name": "logger1",
"level": 2,
"node": 1
},
{
"name": "logger2",
"level": 3,
"node": 1
}]
I expect the objects to be created and displayed to the client with success status. Currently, the objects are created in the db successfully but a 500: Server Error is returned and this is the stacktrace I see on Django server:
Internal Server Error: /api/clustering/loglevel/set/
Traceback (most recent call last):
File "/opt/cisco/env/iris/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/opt/cisco/env/iris/lib/python3.6/site-packages/django/core/handlers/base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/opt/cisco/env/iris/lib/python3.6/site-packages/django/core/handlers/base.py", line 143, in _get_response
response = response.render()
File "/opt/cisco/env/iris/lib/python3.6/site-packages/django/template/response.py", line 106, in render
self.content = self.rendered_content
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/response.py", line 72, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/renderers.py", line 724, in render
context = self.get_context(data, accepted_media_type, renderer_context)
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/renderers.py", line 697, in get_context
'post_form': self.get_rendered_html_form(data, view, 'POST', request),
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/renderers.py", line 520, in get_rendered_html_form
return self.render_form_for_serializer(serializer)
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/renderers.py", line 528, in render_form_for_serializer
serializer.data,
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/serializers.py", line 765, in data
ret = super(ListSerializer, self).data
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/serializers.py", line 266, in data
self._data = self.get_initial()
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/serializers.py", line 600, in get_initial
return self.to_representation(self.initial_data)
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/serializers.py", line 683, in to_representation
self.child.to_representation(item) for item in iterable
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/serializers.py", line 683, in <listcomp>
self.child.to_representation(item) for item in iterable
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/serializers.py", line 527, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/opt/cisco/env/iris/lib/python3.6/site-packages/rest_framework/relations.py", line 257, in to_representation
return value.pk
AttributeError: 'int' object has no attribute 'pk'
python==3.6
django==2.2.2
drf==3.8.2
The serializer.data property is only valid if you have a saved an instance to the serializer.
Either call serializer.save() or use serializer.validated_data to access data prior to saving.
Checkout this link for further information.
Had to handle this error by updating to_representation method on the PrimaryKeyRelatedField class
class NodePrimaryKeyField(serializers.PrimaryKeyRelatedField):
"""
Custom DRF serializer field for proper handling of
Node Foreign Key by ListSerializer on validation error
"""
def to_representation(self, value):
"""
Return pk value of serialized Node object
if available else return given ID value
"""
if self.pk_field is not None:
return self.pk_field.to_representation(value.pk)
return getattr(value, 'pk', value)

ValueError - The annotation 'status' conflicts with a field on the model django

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.

Django REST Framework - get_queryset: 'MyModel' object has no attribute 'model'

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

TastyPie data validation issue

I wonder what is the proper way of using TastyPie validation.
I have following resource and model:
from tastypie.resources import ModelResource
class Station(models.Model):
name = models.CharField(max_length=20)
city = models.ForeignKey(City)
class StationResource(ModelResource):
city = fields.ForeignKey(CityResource, 'city')
class Meta:
queryset = caModels.Station.objects.all()
resource_name = 'Station'
authorization = Authorization()
validation=FormValidation(form_class=StationForm)
max_limit = None
And I also want to use a ModelForm to validate data:
class StationForm(forms.ModelForm):
class Meta:
model = caModels.Station
def clean_city(self):
return self.cleaned_data['city']
The following query works fine:
curl --dump-header - -H "Content-Type: application/json" -X POST --data '{"city": "/resources/City/89/", "name": "station_1", <and other fields here>}' "http://localhost:8000/resources/Station/?format=json"
HTTP/1.0 201 CREATED
Date: Thu, 06 Feb 2014 13:10:14 GMT
Server: WSGIServer/0.1 Python/2.7.4
Vary: Accept, Cookie
Content-Type: text/html; charset=utf-8
Location: http://localhost:8000/resources/Station/3/
But when I remove city from request (but this field is required) instead of message 'This field is required' I get the following traceback:
Traceback (most recent call last):
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 77, in wrapped_view
return view_func(*args, **kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 217, in wrapper
response = callback(request, *args, **kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 459, in dispatch_list
return self.dispatch('list', request, **kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 491, in dispatch
response = method(request, **kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 1357, in post_list
updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs))
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 2149, in obj_create
bundle = self.full_hydrate(bundle)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 909, in full_hydrate
value = field_object.hydrate(bundle)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/fields.py", line 732, in hydrate
value = super(ToOneField, self).hydrate(bundle)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/fields.py", line 165, in hydrate
elif self.attribute and getattr(bundle.obj, self.attribute, None):
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 389, in __get__
raise self.field.rel.to.DoesNotExist
DoesNotExist
This error happens even before I can validate the data in the form (validation is the first process of save procedure looks like).
.../tastypie/resources.py:
def obj_create(self, bundle, **kwargs):
"""
A ORM-specific implementation of ``obj_create``.
"""
bundle.obj = self._meta.object_class()
for key, value in kwargs.items():
setattr(bundle.obj, key, value)
self.authorized_create_detail(self.get_object_list(bundle.request), bundle)
bundle = self.full_hydrate(bundle)
return self.save(bundle)
def save(self, bundle, skip_errors=False):
self.is_valid(bundle)
...
Can somebody point me where I am wrong, or may be I missed something and this way of validation is completely wrong from TastyPie point of view?
I think your question is very interesting.
I decided to dig in a little in subject..
Here is what I've found.
The docs:
blank
As we see this description is pretty similar to what we already know from Django.
The Code base:
hydrate
If you don't say explicitly Tastypie will does "expect" this field to be there.
Short conclusion: I think about resource like something beyond the models and the Meta may be much different regards to needs, that can give you more flexibility for instance.
Potential solutions:
Say to Tastypie pass it if its blank. Anyway model validation will not pass it.
class StationResource(ModelResource):
city = fields.ForeignKey(CityResource, 'city', blank=True)
Or Add default to hydrate.
class StationResource(ModelResource):
city = fields.ForeignKey(CityResource, 'city')
def hydrate(self, bundle):
if not hasattr(bundle, 'city'):
bundle.data['city'] = None
return bundle
Conclusion: This is in fact quite misleading but on other hand Tastypie is still under development, maybe docs will cover it better or this will change or there is plan to changed it.
If you are more interested there is many issues debated on github: like this one similar to your question: issue

MultiValueDictKeyError when editing inline admin object

I am designing a simple MCQ application using the ManyToOne relationship from django website, django version 1.6.1. I have an inline admin form which supposedly allows me to add / edit answers to a given question from the same changeform. However, if after saving a question with its answers once, i am unable to edit / add answers from the same form and get a MultiValueDictKeyError. My models are:
class SBA (models.Model):
question = models.TextField(blank=False)
system = models.CharField(max_length=3, choices=pacscon.System.which_system)
case = models.ForeignKey('pacscon.Patient')
created = models.DateField(auto_now_add=True)
reference = models.TextField(blank=True)
def __unicode__(self):
return self.question
class Answer(models.Model):
id = models.AutoField(primary_key=True)
body = models.TextField()
correct = models.BooleanField(default=False)
sba = models.ForeignKey(SBA, null=True)
def __unicode__(self):
return self.body
the admin.py looks like this :
from models import Answer, SBA, Mnemonic
#from django import forms
from django.contrib import admin
class AnswerInline(admin.StackedInline):
model = Answer
extra = 2
class SBAAdmin(admin.ModelAdmin):
fieldsets = (
(None, {
'fields': ('question', 'system', 'case', 'reference')
}),
)
inlines = [
AnswerInline,
]
readonly_fields = ('created',)
admin.site.register(SBA, SBAAdmin)
admin.site.register(Answer)
admin.site.register(Mnemonic)
And the error message is :
MultiValueDictKeyError at /admin/knowledge/sba/1/
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
114. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in wrapper
432. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
99. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
52. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in inner
198. return view(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper
29. return bound_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
99. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func
25. return func(self, *args2, **kwargs2)
File "/usr/local/lib/python2.7/dist-packages/django/db/transaction.py" in inner
339. return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in change_view
1229. if all_valid(formsets) and form_validated:
File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py" in all_valid
415. if not formset.is_valid():
File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py" in is_valid
292. err = self.errors
File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py" in errors
267. self.full_clean()
File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py" in full_clean
314. form = self.forms[i]
File "/usr/local/lib/python2.7/dist-packages/django/utils/functional.py" in __get__
49. res = instance.__dict__[self.func.__name__] = self.func(instance)
File "/usr/local/lib/python2.7/dist-packages/django/forms/formsets.py" in forms
133. forms = [self._construct_form(i) for i in xrange(self.total_form_count())]
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py" in _construct_form
848. form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py" in _construct_form
564. pk = self.data[pk_key]
File "/usr/local/lib/python2.7/dist-packages/django/utils/datastructures.py" in __getitem__
301. raise MultiValueDictKeyError(repr(key))
Exception Type: MultiValueDictKeyError at /admin/knowledge/sba/1/
Exception Value: "u'answer_set-0-id'"
I have searched similar requests on google and stackoverflow and my django package is fully upto date (including admin inline templates as suggested in some other answers). Will appreciate any help. Thanks
P.S This is almost certainly a bug because I can replicate the problem on official django "Polls" tutorial which uses a similar ManyToOne relationship model.
In Django <= 1.7.3, I needed to change the primary key field of my model to AutoField:
wrong:
class Answer(models.Model):
id = IntegerField(primary_key=True)
correct:
class Answer(models.Model):
id = AutoField(primary_key=True)
See
https://code.djangoproject.com/ticket/15665
I have similar issue which was solved by update django-grappelli. If you did not use it, check your packages maybe you find what can affect work of admin site.
pip freeze | grep django- will show you current packages with versions
This answer https://stackoverflow.com/a/20246225/554807 has the explanation.
The best fix is actually to get silverfix's branch of nested-inlines: https://github.com/silverfix/django-nested-inlines
This has the fix mentioned in that answer, and others.
After migrating an application from Django==1.4.20 to Django==1.8.3 i had an outdated templates_django/admin/edit_inline/stacked.html and templates_django/admin/edit_inline/tabular.html files.
So i have just removed them and everything works fine now.
You can also upgrade them to your current django version instead of deleting.