MultiValueDictKeyError when editing inline admin object - django

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.

Related

Role choice field data ins't saved for UserRegsitrationForm django

The following error message appears after I submit the SignUpform:
'NoneType' object has no attribute '_inc_path'
This issue is related to the role choice field of my CustomUser model. The models function perfectly without the role field and all forms are displayed and saved correctly.
I suspect my choice field form does not pass/save correctly the input values to the CustomUser model.
Any input would be highly appreciated.
Models.py:
class CustomUser(AbstractUser):
display_name = models.CharField(verbose_name=("Display name"), max_length=30, help_text=("Will be shown e.g. when commenting"))
...
country = CountryField(blank=True, null=True)
...
role = models.CharField(choices = ROLES, max_length = 50, default = "regular_user",)
...
class Meta:
ordering = ['last_name']
def get_absolute_url(self):
return reverse('account_profile')
def __str__(self):
return f"{self.username}: {self.first_name} {self.last_name}" ```
forms.py:
class SignupForm(forms.Form):
first_name = forms.CharField(max_length=30, label=_("First name"))
last_name = forms.CharField(max_length=30, label=_("Last name"))
display_name = forms.CharField(max_length=30, label=_("Display name"), help_text=_("Will be shown e.g. when commenting."))
role = forms.ChoiceField(choices = ROLES, label="Role", initial='Regular_user', widget=forms.Select(), required=True)
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.display_name = self.cleaned_data['display_name']
user.role = self.cleaned_data['role']
user.save()
users/create.html:
{% extends "wagtailusers/users/create.html" %}
{% block extra_fields %}
...
{% include "wagtailadmin/shared/field_as_li.html" with field=form.role %}
...
{% endblock extra_fields %}
settings.py:
AUTH_USER_MODEL = 'userauth.CustomUser'
WAGTAIL_USER_CREATION_FORM ='userauth.forms.WagtailUserCreationForm'
WAGTAIL_USER_EDIT_FORM = 'userauth.forms.WagtailUserEditForm'
WAGTAIL_USER_CUSTOM_FIELDS = ['display_name',... 'role', ...]
ACCOUNT_SIGNUP_FORM_CLASS = 'userauth.forms.SignupForm'
Error log:
2022-10-17 10:16:35,894: Internal Server Error: /accounts/signup/
Traceback (most recent call last):
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/django/views/generic/base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/django/utils/decorators.py", line 46, in _wrapper
return bound_method(*args, **kwargs)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/allauth/decorators.py", line 20, in wrap
resp = function(request, *args, **kwargs)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/django/utils/decorators.py", line 46, in _wrapper
return bound_method(*args, **kwargs)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/django/views/decorators/debug.py", line 92, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/allauth/account/views.py", line 234, in dispatch
return super(SignupView, self).dispatch(request, *args, **kwargs)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/allauth/account/views.py", line 77, in dispatch
response = super(RedirectAuthenticatedUserMixin, self).dispatch(
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/allauth/account/views.py", line 207, in dispatch
return super(CloseableSignupMixin, self).dispatch(request, *args, **kwargs)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/django/views/generic/base.py", line 119, in dispatch
return handler(request, *args, **kwargs)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/allauth/account/views.py", line 105, in post
response = self.form_valid(form)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/allauth/account/views.py", line 252, in form_valid
return complete_signup(
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/allauth/account/utils.py", line 183, in complete_signup
signals.user_signed_up.send(
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/django/dispatch/dispatcher.py", line 176, in send
return [
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/django/dispatch/dispatcher.py", line 177, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
File "/home/teki/fommestyuta/users/models.py", line 38, in create_user_group_and_pages
home.add_child(instance=article_index_page)
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/treebeard/mp_tree.py", line 1083, in add_child
return MP_AddChildHandler(self, **kwargs).process()
File "/home/teki/.virtualenvs/bup/lib/python3.9/site-packages/treebeard/mp_tree.py", line 377, in process
newobj.path = self.node.get_last_child()._inc_path()
AttributeError: 'NoneType' object has no attribute '_inc_path'
create_user_group_and_pages:
from django.db import models
from django.contrib.auth.models import Group, Permission
from django.dispatch import receiver
from allauth.account.signals import user_signed_up
from wagtail.core.models import Page, GroupPagePermission, GroupCollectionPermission, Collection
from cms.models import ArticleIndexPage
#receiver(user_signed_up)
def create_user_group_and_pages(sender, **kwargs):
"""
When a new user signs up create a unique group and page for them.
Assign it the appropriate permission for admin, page and collection access.
"""
# Grab the new user
user = kwargs['user']
# Create a group object that matches their username
new_group, created = Group.objects.get_or_create(name=user.username)
# Add the new group to the database
user.groups.add(new_group)
# Create new permission to access the wagtail admin
access_admin = Permission.objects.get(codename='access_admin')
# Add the permission to the group
new_group.permissions.add(access_admin)
# Now start creating page access
# First find the homepage
home = Page.objects.get(slug='home').specific
# Create unique PersonIndexPage for the user
article_index_page = ArticleIndexPage(title=user.username)
# Add PersonIndexPage to homepage as a child
home.add_child(instance=article_index_page)
# Save new page as first revision
article_index_page.save_revision()
# Create new add GroupPagePermission
GroupPagePermission.objects.create(
group=new_group,
page=article_index_page,
permission_type='add'
)
# Create new GroupCollectionPermission for Profile Images collection
GroupCollectionPermission.objects.create(
group=new_group,
collection=Collection.objects.get(name='Images'),
permission=Permission.objects.get(codename='add_image')
)
It looks like the page tree data in your database has become inconsistent, causing it to fail when creating the new ArticleIndexPage. (Specifically, the record for the 'home' page shows that it has existing child pages, meaning that it has to look at those child page records to find the correct position for the new page - but when it tries retrieving those child pages, none are being returned.) This may have happened due to a previous error occurring part-way through creating or deleting a page.
To fix this, run: ./manage.py fixtree

How to get rid of TypeError at /task_create/, quote_from_bytes() expected bytes

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

django rest framework OPTIONS 500

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

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

Filter Django Queryset: ValueError

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'