According to the Django documentation here: https://docs.djangoproject.com/en/2.1/ref/models/expressions/#using-f-with-annotations
I can do date calculations using ExpressionWrapper. I tried to use it like this:
sprints = Sprint.objects.annotate(
duration=models.Case(
models.When(
Q(started__isnull=False) &
Q(done__isnull=False),
then=models.Value(
models.ExpressionWrapper(
(models.F('done') - models.F('started')),
output_field=models.DateTimeField()
))
),
models.When(
Q(started__isnull=False) &
Q(done__isnull=True),
then=models.Value(
models.ExpressionWrapper(
(Now() - models.F('started')),
output_field=models.DateTimeField(),
))
),
output_field=models.DateTimeField()
)).values_list('name',
'planned',
'started',
'done',
'duration')
But I get an error from pytz trying to do auto-localisation on the ExpressionWrapper:
Traceback (most recent call last):
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/viewsets.py", line 103, in view
return self.dispatch(request, *args, **kwargs)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
response = self.handle_exception(exc)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
response = handler(request, *args, **kwargs)
File "/home/phirt/src/core3/src/backend/portal/views/api/transformation.py", line 766, in get_sprint_data_csv
for sprint in sprints:
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/models/query.py", line 272, in __iter__
self._fetch_all()
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/models/query.py", line 1179, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1011, in apply_converters
value = converter(value, expression, connection)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/db/backends/mysql/operations.py", line 247, in convert_datetimefield_value
value = timezone.make_aware(value, self.connection.timezone)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/django/utils/timezone.py", line 269, in make_aware
return timezone.localize(value, is_dst=is_dst)
File "/home/phirt/local/venv/core3/lib/python3.6/site-packages/pytz/__init__.py", line 226, in localize
if dt.tzinfo is not None:
AttributeError: 'str' object has no attribute 'tzinfo'
And indeed the dt parameter passed to localize in pytz is a string, and it's exactly my ExpressionWrapper expression: ExpressionWrapper(F(done) - F(started))
How can I make this work?
Edit: Here is the sprint model:
class Sprint(BaseModel):
name = models.CharField(max_length=100)
planned = models.DateTimeField(null=True, blank=True)
started = models.DateTimeField(null=True, blank=True)
done = models.DateTimeField(null=True, blank=True)
state = models.CharField(max_length=20, verbose_name='State')
start_planned = models.DateTimeField(blank=True, null=True,
verbose_name='Start Planned')
start_latest = models.DateTimeField(blank=True, null=True,
verbose_name='Start Latest')
enforce_start = models.BooleanField(default=False,
verbose_name='Enforce Start')
class Meta:
ordering = ["name"]
verbose_name = "Sprint"
def __str__(self):
return f'<Sprint name="{self.name}">'
I have made it work by changing the query annotation to the following:
sprints = Sprint.objects.annotate(
duration=models.Case(
models.When(
Q(started__isnull=False) &
Q(done__isnull=False),
then=(models.F('done') - models.F('started')),
),
models.When(
Q(started__isnull=False) &
Q(done__isnull=True),
then=(Now() - models.F('started')),
),
output_field=models.DurationField()
)).values_list('name',
'planned',
'started',
'done',
'duration')
Related
I try to integrate vue tags input http://www.vue-tags-input.com/#/ with my project.
Autocomplete works fine, form also. When I save the form, everything except the category(tags) is saved.
I know that with many to many relationship I have to use save_m2m in view, but when I do this, error appear:
invalid literal for int() with base 10: 'e'
My view:
#login_required
def save_embed(request):
interests = RecipeCategory.objects.all()
if request.method == "POST":
form = AddEmbed(request.POST)
if form.is_valid():
new_embed = form.save(commit=False)
new_embed.added_by = request.user
new_embed.save()
form.save_m2m()
else:
form = AddEmbed()
return render(request, 'embed/embedadd.html', {'form': form,
'interests': interests})
Model:
class Embed(models.Model, Activity):
url = models.URLField(max_length=255, verbose_name='Adres przepisu')
title = models.CharField(max_length=255, verbose_name='Tytuł')
description = models.TextField(verbose_name='Opis', blank=True, null=True)
type = models.CharField(blank=True, max_length=200)
thumbnail_url = models.URLField(max_length=255, blank=True, null=True)
image = models.ImageField(upload_to='recipes', blank=True)
html = models.TextField()
votes = GenericRelation(LikeDislike, related_query_name='embedlikes')
added_by = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
category = TreeManyToManyField(RecipeCategory, blank=True, null=True, related_name='embeds', verbose_name='Kategoria')
slug = AutoSlugField(populate_from='title', unique=True)
Edit - Form
class AddEmbed(ModelForm):
url = forms.URLField(label='Adres przepisu', widget=forms.URLInput(attrs={'v-model': 'embed.url', '#paste':'paste', '#input':'input'}))
title = forms.CharField(widget=forms.HiddenInput(attrs={':value':'embedsinfo.title'}))
description = forms.CharField(widget=forms.HiddenInput(attrs={':value':'embedsinfo.description'}))
thumbnail_url = forms.CharField(widget=forms.HiddenInput(attrs={':value':'embedsinfo.thumbnail_url'}))
html = forms.CharField(widget=forms.HiddenInput(attrs={':value':'embedsinfo.html'}))
category = forms.CharField(widget=forms.HiddenInput(attrs={':value': 'tags'}))
class Meta:
model = Embed
fields = ['url','title', 'description', 'thumbnail_url', 'html', 'category']
Traceback:
Traceback (most recent call last):
File "/data/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/data/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/data/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/data/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/app/recipes/views.py", line 39, in save_embed
form.save_m2m()
File "/data/lib/python3.6/site-packages/django/forms/models.py", line 441, in _save_m2m
f.save_form_data(self.instance, cleaned_data[f.name])
File "/data/lib/python3.6/site-packages/django/db/models/fields/related.py", line 1621, in save_form_data
getattr(instance, self.attname).set(data)
File "/data/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 997, in set
self.add(*new_objs, through_defaults=through_defaults)
File "/data/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 938, in add
through_defaults=through_defaults,
File "/data/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 1065, in _add_items
'%s__in' % target_field_name: new_ids,
File "/data/lib/python3.6/site-packages/django/db/models/query.py", line 892, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/data/lib/python3.6/site-packages/django/db/models/query.py", line 910, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/data/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1290, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/data/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1318, in _add_q
split_subq=split_subq, simple_col=simple_col,
File "/data/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1251, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/data/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1116, in build_lookup
lookup = lookup_class(lhs, rhs)
File "/data/lib/python3.6/site-packages/django/db/models/lookups.py", line 20, in __init__
self.rhs = self.get_prep_lookup()
File "/data/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 59, in get_prep_lookup
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "/data/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 59, in <listcomp>
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "/data/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 972, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'e'
[21/Jun/2020 13:20:22] "POST /recipes/recipe/embed/add/ HTTP/1.1" 500 151931
I am trying to update a ManyToMany field in django while doing this I am getting the following error :
Traceback (most recent call last):
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/rest_framework/decorators.py", line 55, in handler
return func(*args, **kwargs)
File "/home/bhupesh/Desktop/tutorialdb-test/tutorialdb/api/views.py", line 94, in tutorials
updateDB.tags.add(t)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 938, in add
through_defaults=through_defaults,
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 1065, in _add_items
'%s__in' % target_field_name: new_ids,
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/query.py", line 892, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/query.py", line 910, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1290, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1318, in _add_q
split_subq=split_subq, simple_col=simple_col,
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1251, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1116, in build_lookup
lookup = lookup_class(lhs, rhs)
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/lookups.py", line 20, in __init__
self.rhs = self.get_prep_lookup()
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 59, in get_prep_lookup
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 59, in <listcomp>
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "/home/bhupesh/Desktop/tutorialdb-test/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 966, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'A'
Here is my models.py
class tag(models.Model):
name = models.CharField(max_length=100)
created_date = models.DateTimeField(default=timezone.now)
description = models.TextField(blank=True)
def __str__(self):
return self.name
class tutorial(models.Model):
title = models.CharField(max_length=200)
link = models.URLField()
tags = models.ManyToManyField(tag)
category = models.CharField(max_length=200, choices = TUTORIAL_CATEGORIES)
created_date = models.DateTimeField(default=timezone.now)
#cached_property
def __str__(self):
return self.title
I am actually generating title & tags from a custom script that's why the serialzer is incomplete.
I am trying to send the following JSON data :
{
"link":"https://youtu.be/DHvMXvCVQVA",
"category":"video"
}
views.py
#api_view(['GET', 'POST'])
def tutorials(request):
"""
get: Returns all tutorials
post: POST a tutorial
"""
if request.method == 'GET':
tutorials = tutorial.objects.all()
serializer = tutorialSerializer(tutorials, many=True)
return JSONResponse(serializer.data)
elif request.method == 'POST':
postserializer = tutorialPOST(data = request.data)
if postserializer.is_valid():
title, tags = generateTags(request.data['link'])
print(title)
print(tags)
updateDB = tutorial.objects.create(
title = title,
link = request.data['link'],
category = request.data['category'],
created_date = timezone.now
)
for t in tags:
updateDB.tags.set(t)
return JSONResponse({"message " : "submitted" }, status=status.HTTP_202_ACCEPTED)
return JSONResponse({"message":"not_valid"})
Here is serializer.py
class tutorialPOST(serializers.Serializer):
class Meta:
model = tutorial
fields = ('link', 'category')
From what I know it's happening because of the following line in views.py
updateDB.tags.add(t)
You should call timezone.now method, instead of passing the method itself:
updateDB = tutorial.objects.create(
title = title,
link = request.data['link'],
category = request.data['category'],
created_date = timezone.now()
)
You have default value of created_date set correctly:
created_date = models.DateTimeField(default=timezone.now)
so it will be autofilled automatically for you:
updateDB = tutorial.objects.create(
title = title,
link = request.data['link'],
category = request.data['category']
)
Your date fields are giving errors. Just remove all their attributes and add "auto_now=True,auto_now_add=True" to date fields.
I have few django models:
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
phone = models.CharField(
_('phone number'), max_length=16,
unique=True, blank=True, null=True,
default=None, validators=[phone_validator]
)
...
class UserExtension(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
class Meta:
abstract = True
class Worker(UserExtension):
# some fields
class Administrator(UserExtension):
# some fields
View:
class AdministratorListView(ListAPIView):
permission_classes = (AllowAny,)
queryset = Administrator.objects.all()
serializer_class = serializers.AdministratorSerializer
And serializer:
class AdministratorSerializer(serializers.ModelSerializer):
class Meta:
model = Administrator
fields = ('network', 'email')
extra_kwargs = {'email': {'source': 'user.email'}}
But this is not working. Following traceback tell about field does not exist for my model:
Traceback (most recent call last):
File "/home/vagrant/v_env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/vagrant/v_env/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/vagrant/v_env/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vagrant/v_env/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/vagrant/v_env/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/generics.py", line 201, in get
return self.list(request, *args, **kwargs)
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/mixins.py", line 48, in list
return Response(serializer.data)
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 765, in data
ret = super(ListSerializer, self).data
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 262, in data
self._data = self.to_representation(self.instance)
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 683, in to_representation
self.child.to_representation(item) for item in iterable
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 683, in <listcomp>
self.child.to_representation(item) for item in iterable
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 510, in to_representation
fields = self._readable_fields
File "/home/vagrant/v_env/lib/python3.6/site-packages/django/utils/functional.py", line 37, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 376, in _readable_fields
field for field in self.fields.values()
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 363, in fields
for key, value in self.get_fields().items():
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 1047, in get_fields
source, info, model, depth
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 1192, in build_field
return self.build_unknown_field(field_name, model_class)
File "/home/vagrant/v_env/lib/python3.6/site-packages/rest_framework/serializers.py", line 1304, in build_unknown_field
(field_name, model_class.__name__)
django.core.exceptions.ImproperlyConfigured: Field name `user.email` is not valid for model `Administrator`.
I looked at the source code and realized that the value from 'source' is passed to build_field as field_name argument and rest-framework simply cannot find this field ('user.email') in my model (Administrator)
part of get_fields method
build_field method
I've a UserAnalytics object which has a one-to-one relationship with an User.
class UserAnalytics(models.Model):
user = models.ForeignKey(User, related_name='analytics', on_delete=models.CASCADE, null=True)
uptime = models.IntegerField(null=True)
feeds_viewed = models.IntegerField(null=True)
feeds_shared = models.IntegerField(null=True)
I've a Feed object which has a ManyToMany relationship with the UserAnalytics object.
class Feed(Base):
headline = models.CharField(max_length=255)
link = models.CharField(max_length=255, unique=True)
summary = models.TextField()
thumbnail = models.CharField(max_length=512, null=True)
published_date = models.DateTimeField()
views = models.IntegerField(default=0)
shares = models.IntegerField(default=0)
source = models.ForeignKey(Source, on_delete=models.CASCADE, null=True)
reader = models.ManyToManyField(User, through='Bookmark')
viewers = models.ManyToManyField(UserAnalytics)
When I try to add a feed to a UserAnalytics, using this code,
class ReadFeed(views.APIView):
def get(self, request, **kwargs):
try:
user = User.objects.get(id=kwargs.get('user_id'))
analytics = UserAnalytics.objects.get(id=user.id)
except User.DoesNotExist:
return Response({"Error": "User does not exist"}, status=status.HTTP_404_NOT_FOUND)
try:
feed = Feed.objects.get(id=kwargs.get('feed_id'))
feed.views += 1
feed.viewers.add(analytics)
feed.save()
user.analytics.add(feed)
user.analytics.save()
return Response(FeedSerializer(feed).data, status=status.HTTP_200_OK)
except Feed.DoesNotExist:
return Response({"Error": "Feed does not exist"}, status=status.HTTP_404_NOT_FOUND)
This the error that I get,
Traceback (most recent call last):
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/rest_framework/views.py", line 494, in dispatch
response = self.handle_exception(exc)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/rest_framework/views.py", line 454, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/rest_framework/views.py", line 491, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/aggregator/api.py", line 28, in get
feed.viewers.add(user.analytics)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 898, in add
self._add_items(self.source_field_name, self.target_field_name, *objs)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 1045, in _add_items
'%s__in' % target_field_name: new_ids,
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/query.py", line 836, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/query.py", line 854, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1253, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1277, in _add_q
split_subq=split_subq,
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1215, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1085, in build_lookup
lookup = lookup_class(lhs, rhs)
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/lookups.py", line 18, in __init__
self.rhs = self.get_prep_lookup()
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 59, in get_prep_lookup
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 59, in <listcomp>
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "/Users/mstewart/Dropbox/xdrive/ftb/ftb_core_backend/env/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 947, in get_prep_value
return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'RelatedManager'
[28/May/2018 15:55:19] "GET /api/v1/aggregator/read/4/67 HTTP/1.1" 500 18150
TypeError: int() argument must be a string, a bytes-like object or a number, not 'RelatedManager'
What am I doing wrong here?
I think you have edited the error out of your view.
The traceback shows that your file api.py:28 has a line:
feed.viewers.add(user.analytics)
But user.analytics is a one-to-many relation, and thus one user can have several UserAnalytics objects (since many of these can all refer to the same use). As a result user.analytics is not a single object, nor a collection, but a RelatedManager: some sort of manager to manage the related objects.
You can add .all() and perform iterable unpacking to add all the .analytics objects with a single call:
feed.viewers.add(*user.analytics.all())
(notice the asterisk * in the call).
In case every user has at most one UserAnalytics object, you better use a OneToOneField, so:
# only in case a user has *at most* one UserAnalytics object
class UserAnalytics(models.Model):
user = models.OneToOneField(User, related_name='analytics', on_delete=models.CASCADE, null=True)
uptime = models.IntegerField(null=True)
feeds_viewed = models.IntegerField(null=True)
feeds_shared = models.IntegerField(null=True)
In that case a user.analyics will either return the associated UserAnalytics object (given there is one), or - if there is no such object - raise a UserAnalytics.DoesNotExist error.
I'm creating an API endpoint that works and saves data through its API. It works, but my concern is that it throws a KeyError as shown below. I'm not sure if this is an issue with my code. Your help is very much appreciated.
Data:
data = {'title': u'abc', 'career_level': 1}
Serializer:
class JobPostSerializer(serializers.ModelSerializer):
career_level = PrimaryKeyRelatedField(allow_null=True, queryset=CareerLevel.objects.all(), required=False)
title = CharField(allow_blank=True, allow_null=True, max_length=240, required=False)
Model:
class JobPost(models.Model):
career_level = models.ForeignKey(CareerLevel, related_name='jobpost_career', blank=True, null=True)
title = models.CharField(max_length=240, blank=True, null=True)
created_at = models.DateTimeField(db_index=True, auto_now_add=True)
def __str__(self):
return self.title
def __unicode__(self):
return self.title
class Meta:
ordering = ['-created_at']
Error Message:
Internal Server Error: /api/v1/posts/
Traceback (most recent call last):
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/rest_framework/viewsets.py", line 87, in view
return self.dispatch(request, *args, **kwargs)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/rest_framework/mixins.py", line 22, in create
headers = self.get_success_headers(serializer.data)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 503, in data
ret = super(Serializer, self).data
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 241, in data
self._data = self.to_representation(self.validated_data)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 463, in to_representation
attribute = field.get_attribute(instance)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/rest_framework/relations.py", line 157, in get_attribute
return get_attribute(instance, self.source_attrs)
File "/home/ubuntu/panbecopy/src/penv/local/lib/python2.7/site-packages/rest_framework/fields.py", line 78, in get_attribute
instance = instance[attr]
KeyError: u'career_level'
Your serializer definition makes no sense.
JobPostSerializer(data={'title': u'abc', 'career_level': 1}):
It should instead be:
class JobPostSerializer(serializers.ModelSerializer):
That line of yours is more similar to when you want to instantiate the serializer. Something like when you want to check if the input was valid, for example.
job_serializer = JobPostSerializer(data={'title': u'abc', 'career_level': 1})
job_serializer.is_valid()