I am trying to get a user's list with an AJAX request and DRF. But get this error:
Field 'id' expected a number but got 'Henry'.
I'd be grateful for any assistance.
AJAX:
const showUserLists = function(map){
let userName = "Henry";
$.ajax({
type: 'GET',
url: '/api/userlist/',
data: {
'username': userName
},
success: function (data) {
data.forEach(item => {
console.log(item.list_name)
$("#userLists").append("<li class=userlist data-name=\"" + item.list_name + "\">" + item.list_name + "</li>")
})
}
});
};
urls.py:
router = DefaultRouter() #need help understanding router register
router.register('userlist', views.UserListViewSet, basename= 'userlist')
views.py
#this shows all lists for a user
class UserListViewSet(viewsets.ModelViewSet):
serializer_class = UserListSerializer
def get_queryset(self):
name = self.request.GET.get('username', None)
return UserList.objects.filter(user=name)
Serializer:
class UserListSerializer(serializers.ModelSerializer): #this is what we worked on on October 1
class Meta:
model = UserList
fields = ['id', 'user', 'list_name']
class VenueListSerializer(serializers.ModelSerializer):
created = serializers.ReadOnlyField()
class Meta:
model = VenueList
fields = ['id', 'title']
Relevant model:
class UserList(models.Model):
list_name = models.CharField(max_length=255)
user = models.ForeignKey(User, on_delete=models.CASCADE) #is this okay?
def __str__(self):
return self.list_name
Traceback
Traceback (most recent call last):
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1774, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'Henry'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/viewsets.py", line 114, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
raise exc
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/mixins.py", line 38, in list
queryset = self.filter_queryset(self.get_queryset())
File "/Users/x/Desktop/Coding/anybody/anybody1/api/views.py", line 33, in get_queryset
return UserList.objects.filter(user=name)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/query.py", line 942, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/query.py", line 962, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, *args, **kwargs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/query.py", line 969, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1358, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1380, in _add_q
split_subq=split_subq, check_filterable=check_filterable,
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1319, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1165, in build_lookup
lookup = lookup_class(lhs, rhs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/lookups.py", line 24, in __init__
self.rhs = self.get_prep_lookup()
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 115, in get_prep_lookup
self.rhs = target_field.get_prep_value(self.rhs)
File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1778, in get_prep_value
) from e
ValueError: Field 'id' expected a number but got 'Henry'.
Your user is a ForeignKey to the User model, so if you filter on this, it expects the primary key of the User, not the username.
You can however filter on the username of the related User with:
class UserListViewSet(viewsets.ModelViewSet):
serializer_class = UserListSerializer
def get_queryset(self):
name = self.request.GET.get('username', None)
return UserList.objects.filter(user__username=name)
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Related
Im quite new to django but i cant find the solution in the docs
My question:
I have a model with 2 OneToOne relations:
class Slotting(ICSBaseMixin):
# database fields
article = models.OneToOneField(
"ics_stock.Article",
on_delete=models.CASCADE,
related_name="slotting",
null=False
)
article_location = models.OneToOneField(
"ics_stock.ArticleLocation",
on_delete=models.CASCADE,
null=False,
related_name="slotting"
)
def __str__(self):
return str(self.record_id)
class Meta:
db_table = "ICS_Stock_Slotting"
verbose_name = "Slotting"
verbose_name_plural = "Slottings" # noqa
I want to create and save a new instance through a serializer.
serializer:
class SlottingCreateUpdateSerializer(serializers.ModelSerializer):
def update(self, instance, validated_data):
article = validated_data.pop("article")
instance.article_id = article
article_location = validated_data.pop("article_location")
instance.article_location_id = article_location
instance.save()
return instance
def create(self, validated_data):
article_id = validated_data.pop("article")
article = get_object_or_404(
Article,
record_id=article_id
)
article_location_id = validated_data.pop("article_location")
article_location = get_object_or_404(
ArticleLocation,
record_id=article_location_id
)
slotting = Slotting()
slotting.article_location = article_location,
slotting.article = article
slotting.save()
return slotting
Now when trying to serialize and save i get the following error:
raceback (most recent call last):
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\fields\__init__.py", line 1988, in get_prep_value
return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'Article'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\views\generic\base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\000 Projects\Applications\ICS_Django_core\ics_stock\api\views\slotting.py", line 44, in post
instance = validated_data.save()
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\rest_framework\serializers.py", line 212, in save
self.instance = self.create(validated_data)
File "C:\000 Projects\Applications\ICS_Django_core\ics_stock\api\serializers\slotting.py", line 40, in create
article = get_object_or_404(
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\shortcuts.py", line 85, in get_object_or_404
return queryset.get(*args, **kwargs)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\query.py", line 482, in get
clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\query.py", line 1071, in filter
return self._filter_or_exclude(False, args, kwargs)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\query.py", line 1089, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\query.py", line 1096, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\sql\query.py", line 1502, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\sql\query.py", line 1532, in _add_q
child_clause, needed_inner = self.build_filter(
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\sql\query.py", line 1448, in build_filter
condition = self.build_lookup(lookups, col, value)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\sql\query.py", line 1273, in build_lookup
lookup = lookup_class(lhs, rhs)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\lookups.py", line 27, in __init__
self.rhs = self.get_prep_lookup()
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\lookups.py", line 85, in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
File "C:\000 Projects\Applications\ICS_Django_core\venv\lib\site-packages\django\db\models\fields\__init__.py", line 1990, in get_prep_value
raise e.__class__(
TypeError: Field 'record_id' expected a number but got <Article: test article>.
Now im googling and looking for a whole day but i still dont know what im doing wrong.
What do i need to refactor to be able to fix the bug.
I created a serializer class to inherrit from that uses a dict input from the Meta class.
class RelatedModelSerializer(serializers.ModelSerializer):
"""
serializes all relationship based models
added field for Meta class
- relationships: dict[str:Model]
Create and update method adds all fields from relationships with the primary key with from model described in relationships dict and saves and raises HTTP404 when object not found
- Arjen Keller
"""
class Meta:
relationships = {}
model = None
def create(self, validated_data):
for key in frozenset(validated_data):
if self.Meta.relationships and key in self.Meta.relationships:
validated_data[f"{key}_id"] = get_object_or_404(
self.Meta.relationships[key],
record_id=validated_data.pop(key).id
).id
return self.Meta.model.objects.create(**validated_data)
def update(self, instance, validated_data):
for key in frozenset(validated_data):
setattr(
instance, f"{key}_id",
validated_data.pop(key)
) if self.Meta.relationships and key in self.Meta.relationships and get_object_or_404(
self.Meta.relationships[key],
record_id=validated_data[key].id
).id else setattr(
instance,
f"{key}",
validated_data.pop(key)
)
instance.save(**validated_data)
return instance
i hope it helps somebody.
I'm trying to create a structure where a list of books read is kept. I had set up a structure, but if the read finished statement is checked, it adds a new record. What I want to do is to create only 1 record according to that user and book id value and constantly update this record. When I want to do this, I get the following error, I cannot access the book id value. There are many similar questions, but I couldn't make the right application, I need suggestions.
Traceback (most recent call last):
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\fields\__init__.py", line 1823, in get_prep_value
return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'Book'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\views\generic\base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "E:\!Staj\bookorbooks\env\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "E:\!Staj\bookorbooks\env\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "E:\!Staj\bookorbooks\env\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\rest_framework\generics.py", line 190, in post
return self.create(request, *args, **kwargs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\rest_framework\mixins.py", line 19, in create
self.perform_create(serializer)
File "E:\!Staj\bookorbooks\bookorbooks\book\api\views\reading_history_views.py", line 32, in perform_create
obj_lst = ReadingHistory.objects.filter(book=book, child=child)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\query.py", line 941, in filter
return self._filter_or_exclude(False, args, kwargs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\query.py", line 961, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\query.py", line 968, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\sql\query.py", line 1393, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\sql\query.py", line 1412, in _add_q
child_clause, needed_inner = self.build_filter(
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\sql\query.py", line 1347, in build_filter
condition = self.build_lookup(lookups, col, value)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\sql\query.py", line 1193, in build_lookup
lookup = lookup_class(lhs, rhs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\lookups.py", line 25, in __init__
self.rhs = self.get_prep_lookup()
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\fields\related_lookups.py", line 117, in get_prep_lookup
self.rhs = target_field.get_prep_value(self.rhs)
File "E:\!Staj\bookorbooks\env\lib\site-packages\django\db\models\fields\__init__.py", line 1825, in get_prep_value
raise e.__class__(
TypeError: Field 'id' expected a number but got <Book: Example Book 1>.
Model
class ReadingHistory(AbstractBookBaseModel):
IS_FINISHED = ((False,
BookStrings.ReadingHistoryStrings.is_finished_false),
(True, BookStrings.ReadingHistoryStrings.is_finished_true))
book = models.ForeignKey(
"book.Book",
on_delete=models.CASCADE,
related_name="book_reading_history",
verbose_name=BookStrings.ReadingHistoryStrings.book_verbose_name)
child = models.ForeignKey(
"account.ChildProfile",
on_delete=models.CASCADE,
related_name="child_reading_history",
verbose_name=BookStrings.ReadingHistoryStrings.child_verbose_name)
is_finished = models.BooleanField(
choices=IS_FINISHED,
verbose_name=BookStrings.ReadingHistoryStrings.is_finished_verbose_name
)
class Meta:
verbose_name = BookStrings.ReadingHistoryStrings.meta_verbose_name
verbose_name_plural = BookStrings.ReadingHistoryStrings.meta_verbose_name_plural
def __str__(self):
return f"{self.child.user.first_name} {self.child.user.last_name} - \"{self.book.name}\" "
Serializer
class ReadingHistoryCreateSerializer(ModelSerializer):
class Meta:
model = ReadingHistory
exclude = ["child"]
# def create(self, validated_data):
# """
# If the user wants to add the same student to a class for the second time, it will throw an error.
# """
# created = self.Meta.model.objects.get(child = validated_data["child"], book = validated_data["book"])
# if not created:
# instance = self.Meta.model.objects.create(**validated_data)
# return instance
# else:
# is_finished_value = created.is_finished
# if is_finished_value == validated_data["is_finished"]:
# pass
# else:
# obj = self.Meta.model.objects.update(child = validated_data["child"], book = validated_data["book"], is_finished = validated_data["is_finished"])
# return obj
View
class AddReadingHistoryAPIView(CreateAPIView):
queryset = ReadingHistory.objects.all()
serializer_class = ReadingHistoryCreateSerializer
# def perform_create(self, serializer):
# return serializer.save(child=self.request.user.user_child)
def perform_create(self, serializer):
book = serializer.validated_data.get('book', ),
is_finished = serializer.validated_data.get('is_finished', )
child = self.request.user.user_child
obj_lst = ReadingHistory.objects.filter(book=int(book), child=child)
if obj_lst:
obj_lst.update(is_finished=is_finished)
else:
ReadingHistory.objects.create(book=book,
child=child,
is_finished=is_finished)
I'm using django-mptt to create a tree-like structure for my Section model. Unfortunately, when I go to serialize it with drf-writable-nested, I get an error. This error only occurs when the url field is added to the serializer.
Also, when I remove uuid from the custom lookup field, the error is just replaced with pk.
I found this: https://stackoverflow.com/a/55173445/9137820, but I'm not accessing any of the data directly, so I'm not sure how that could be the issue.
Code:
# models.py
class Section(MPTTModel, TimeStampedModel):
uuid = models.UUIDField(default=uuid_lib.uuid4, editable=False)
name = models.CharField(max_length=255, unique=True)
objects = TreeManager()
parent = TreeForeignKey('self', related_name='section_children', on_delete=models.CASCADE, null=True, blank=True)
# serializers.py
class SectionSerializer(UniqueFieldsMixin, WritableNestedModelSerializer):
children = serializers.ListField(source='get_children', child=RecursiveField())
class Meta:
model = Section
fields = ['url', 'uuid', 'name', 'children']
extra_kwargs = {
'url': {'lookup_field': 'uuid'},
}
# views.py
class SectionDetail(generics.RetrieveUpdateDestroyAPIView, viewsets.GenericViewSet):
queryset = Section.objects.all()
serializer_class = SectionSerializer
lookup_field = 'uuid'
Traceback:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/rest_framework/viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 75, in update
return Response(serializer.data)
File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 548, in data
ret = super().data
File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 246, in data
self._data = self.to_representation(self.instance)
File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 515, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/usr/local/lib/python3.9/site-packages/rest_framework/fields.py", line 1661, in to_representation
return [self.child.to_representation(item) if item is not None else None for item in data]
File "/usr/local/lib/python3.9/site-packages/rest_framework/fields.py", line 1661, in <listcomp>
return [self.child.to_representation(item) if item is not None else None for item in data]
File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 515, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/usr/local/lib/python3.9/site-packages/rest_framework/relations.py", line 399, in to_representation
url = self.get_url(value, self.view_name, request, format)
File "/usr/local/lib/python3.9/site-packages/rest_framework/relations.py", line 335, in get_url
lookup_value = getattr(obj, self.lookup_field)
Exception Type: AttributeError at /api/v1/sections/3b15cbda-f61e-4a00-89fb-817beed10b14/
Exception Value: 'collections.OrderedDict' object has no attribute 'uuid'
I did some digging and this is what I can find. Dictionaries and OrderedDicts don't save keys and values as class attributes. So you cant retrieve them using getattr(). You need to request a method or attribute like dict.keys() or dict.values() from the OrderedDict. You can't use a key name.
See this example:
from collections import OrderedDict
g = OrderedDict()
g['test'] = 1
g = getattr(g, 'values')
print(list(g())[0])
That works fine but if you changed
g = getattr(g, 'values')
to
g = getattr(g, 'test')
It produces the same error you're experiencing
I have a model Condition that has a field symptoms, which takes multiple different Symptoms objects. Whenever, I make a POST request to create a Condition object, I get the following error:
'Condition: epilepsy' needs to have a value for field "condition" before this many-to-many relationship can be used.
The above 'Condition: epilepsy' is nested between <>, but theres a formatting issue with posting that.
Here is my Condition model:
class Condition(models.Model):
class Treatment():
SURGERY, NON_INVASIVE, PRESCRIPTION_MEDICINE, NONE = range(4)
CHOICES = (
(SURGERY, 'Surgery'),
(NON_INVASIVE, 'Non-Invasive Treatment'),
(PRESCRIPTION_MEDICINE, 'Prescription Medicine'),
(NONE, 'None')
)
class Medicalfield(models.Model):
ONCOLOGY, CARDIOLOGY, NEPHROLOGY, PEDIATRICS, ENDOCRONOLOGY, PSYCHOLOGY = range(6)
CHOICES = (
(ONCOLOGY, 'Oncology'),
(CARDIOLOGY, 'Cardiology'),
(NEPHROLOGY, 'Nephrology'),
(PEDIATRICS, 'Pediatrics'),
(ENDOCRONOLOGY, 'Endocronology'),
(PSYCHOLOGY, 'Psychology')
)
name = models.CharField(max_length=200)
contagious = models.BooleanField()
treatable = models.BooleanField()
treatment = models.IntegerField(choices=Treatment.CHOICES, null=True)
severeity = models.IntegerField(default=0)
symptoms = models.ManyToManyField('Symptom', blank=True)
medicalfield = models.IntegerField(choices=Medicalfield.CHOICES, null=True)
new = ConditionManager()
def __unicode__(self):
return u"%s" % ( self.name )
Here is my Serializer
class ConditionSerializer(serializers.ModelSerializer):
def create(self, validated_data):
attrs = validated_data
request = self.context['request']
return Condition.new.create_condition(**attrs)
class Meta:
model = Condition
fields = ('id', 'treatment', 'name', 'contagious', 'treatable', 'treatment', 'severeity', 'symptoms', 'medicalfield')
Here is the Manager
class ConditionManager(models.Manager):
use_in_migrations = True
use_for_related_fields=True
def create_condition(self, *args, **kwargs):
condition_obj = conditions.models.Condition(name=kwargs['name'], contagious=kwargs['contagious'], treatable=kwargs['treatable'], treatment=kwargs['treatment'], severeity=kwargs['severeity'], symptoms=kwargs['symptoms'], medicalfield=kwargs['medicalfield'])
condition_obj.save()
return condition_obj
And here is the View
#api_view(['POST'])
#permission_classes((AllowAny, ))
def create_condition(request):
context = {'request': request}
symptoms = request.data['symptoms']
symptoms = Symptom.objects.filter(name__in=symptoms)
s = []
for symptom in symptoms:
s.append(symptom.pk)
request.data['symptoms'] = s
serializer = ConditionSerializer(data=request.data, context=context)
if serializer.is_valid():
serializer.save()
return response.Response(serializer.data, status=201)
return response.Response(serializer.errors, status=400)
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 477, in dispatch
response = self.handle_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 437, in handle_exception
self.raise_uncaught_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 474, in dispatch
response = handler(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/decorators.py", line 52, in handler
return func(*args, **kwargs)
File "/Users/user/medicalrecords/conditions/views.py", line 28, in create_condition
serializer.save()
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 214, in save
self.instance = self.create(validated_data)
File "/Users/user/medicalrecords/conditions/serializers.py", line 24, in create
return Condition.new.create_condition(**attrs)
File "/Users/user/medicalrecords/conditions/managers.py", line 17, in create_condition
condition_obj = conditions.models.Condition(name=kwargs['name'], contagious=kwargs['contagious'], treatable=kwargs['treatable'], treatment=kwargs['treatment'], severeity=kwargs['severeity'], symptoms=kwargs['symptoms'], medicalfield=kwargs['medicalfield'])
File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 550, in __init__
setattr(self, prop, kwargs[prop])
File "/Library/Python/2.7/site-packages/django/db/models/fields/related_descriptors.py", line 499, in __set__
manager = self.__get__(instance)
File "/Library/Python/2.7/site-packages/django/db/models/fields/related_descriptors.py", line 476, in __get__
return self.related_manager_cls(instance)
File "/Library/Python/2.7/site-packages/django/db/models/fields/related_descriptors.py", line 783, in __init__
(instance, self.source_field_name))
ValueError: "<Condition: epilepsy>" needs to have a value for field "condition" before this many-to-many relationship can be used.
[22/Feb/2017 20:01:45] "POST /conditions/new/condition/ HTTP/1.1" 500 15799
traceback from #snakefcz 's answer
Internal Server Error: /conditions/new/condition/
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 477, in dispatch
response = self.handle_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 437, in handle_exception
self.raise_uncaught_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 474, in dispatch
response = handler(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/decorators.py", line 52, in handler
return func(*args, **kwargs)
File "/Users/user/medicalrecords/conditions/views.py", line 45, in create_condition
return response.Response(serializer.data, status=201)
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 527, in data
ret = super(Serializer, self).data
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 262, in data
self._data = self.to_representation(self.instance)
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 496, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 643, in to_representation
self.child.to_representation(item) for item in iterable
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 479, in to_representation
fields = self._readable_fields
File "/Library/Python/2.7/site-packages/django/utils/functional.py", line 35, in get
res = instance.dict[self.name] = self.func(instance)
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 373, in _readable_fields
field for field in self.fields.values()
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 359, in fields
for key, value in self.get_fields().items():
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 1010, in get_fields
fields[field_name] = field_class(**field_kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/fields.py", line 733, in init
super(CharField, self).init(**kwargs)
TypeError: init() got an unexpected keyword argument 'view_name'
You'll need to create a Symptom serializer in addition to the Condition one. Your ConditionSerializer should look something like:
class ConditionSerializer(serializers.ModelSerializer):
symptoms = SymptomSerializer(read_only=True, many=True, allow_null=True)
class Meta:
model = Condition
fields = ('id', 'treatment', 'name', 'contagious', 'treatable', 'treatment', 'severeity', 'symptoms', 'medicalfield')
def create(self, validated_data):
attrs = validated_data
request = self.context['request']
return Condition.new.create_condition(**attrs)
## Try it
#api_view(['POST'])
#permission_classes((AllowAny, ))
def create_condition(request):
context = {'request': request}
serializer = ConditionSerializer(data=request.data, context=context)
if serializer.is_valid():
condition = serializer.save()
symptoms = request.data['symptoms']
for symp in symptoms:
symptom = Symptom.objects.get(id=symp) ## if it's id's you are passing
condition.symptoms.add(symptom)
return response.Response(serializer.data, status=201)
return response.Response(serializer.errors, status=400)
I have this Serializer:
class LikeSerializer(serializers.ModelSerializer):
user = serializers.PrimaryKeyRelatedField(queryset=ExtUser.objects.all(), required=False, allow_null=True, default=None)
class Meta:
model = Like
field = ('user', 'post')
def create(self, validated_data):
post = Post(id=validated_data['post'], author=validated_data['user'])
#post=Post.objects.get(pk=validated_data['post'])
post.rating += 1
print(post)
post.save()
return Like.objects.create(**validated_data)
And I get error, when i trying to save Like object TypeError: int() argument must be a string or a number, not 'Post'
Trying to add int(), but it not helps, I think I not correct update Post object
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/Library/Python/2.7/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/rest_framework/decorators.py", line 53, in handler
return func(*args, **kwargs)
File "/Users/olegklimakov/Documents/6rp/likes/views.py", line 19, in send_like
serializer.save(user=request.user, isLiked=True)
File "/Library/Python/2.7/site-packages/rest_framework/serializers.py", line 191, in save
self.instance = self.create(validated_data)
File "/Users/olegklimakov/Documents/6rp/likes/serializers.py", line 39, in create
post.save()
File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 700, in save
force_update=force_update, update_fields=update_fields)
File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 728, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 793, in _save_table
forced_update)
File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 823, in _do_update
filtered = base_qs.filter(pk=pk_val)
File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 790, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 808, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/Library/Python/2.7/site-packages/django/db/models/sql/query.py", line 1243, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/Library/Python/2.7/site-packages/django/db/models/sql/query.py", line 1269, in _add_q
allow_joins=allow_joins, split_subq=split_subq,
File "/Library/Python/2.7/site-packages/django/db/models/sql/query.py", line 1203, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/Library/Python/2.7/site-packages/django/db/models/sql/query.py", line 1099, in build_lookup
return final_lookup(lhs, rhs)
File "/Library/Python/2.7/site-packages/django/db/models/lookups.py", line 19, in __init__
self.rhs = self.get_prep_lookup()
File "/Library/Python/2.7/site-packages/django/db/models/lookups.py", line 57, in get_prep_lookup
return self.lhs.output_field.get_prep_lookup(self.lookup_name, self.rhs)
File "/Library/Python/2.7/site-packages/django/db/models/fields/__init__.py", line 744, in get_prep_lookup
return self.get_prep_value(value)
File "/Library/Python/2.7/site-packages/django/db/models/fields/__init__.py", line 976, in get_prep_value
return int(value)
TypeError: int() argument must be a string or a number, not 'Post'
Post model:
class Post(models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
title = models.CharField(max_length=250) # Max Length of title = 250
description = models.CharField(max_length=1000) # Max Length = 1000 chars
rating = models.IntegerField(default=1)
author = models.ForeignKey('extuser.ExtUser', blank=True, null=True)
def __unicode__(self):
return u"%s" % self.id
It seems like inside the statement
"Post(id=validated_data['post'], author=validated_data['user'])",
validated_data['post'] gives you a Post object, not a int object,
but the 'id' inside the Post model expect a int object.
That probably is the reason you get the error.
#transactional
def create(self, validated_data):
post = Post(id=validated_data['post'], author=validated_data['user'])
post.rating += 1
post.save()
return super(self, LikeSerializer).create(validated_data)
Its good to let ModelSerializer create do its job, also note you definitely want to use transaction to keep data consistent
Also, code below creates new Post entity:
post = Post(...)
post.save()
You definitely need to get existent Post entity instead
Post.objects.filter(...).first()