Have wasted alot of time researching and trying to figure out how to implement bookmarks in django. I tried CBV but i gave up. I tried fbv but I keep on getting this error:
TypeError at 'Bookmark' instance expected, got SimpleLazyObject: User: ****
Here is my View:
@login_required
def company_bookmark(request, slug):
user = request.user
model = get_object_or_404(Company, slug=slug)
if user.is_authenticated:
if model.bookmark.filter(id=user.id).exists():
model.bookmark.remove(request.user)
else:
model.bookmark.add(request.user)
return HttpResponseRedirect(model.get_absolute_url())
else:
messages.warning(request, 'you must be authenticated first')
I wrap it in condition statement and still got same error, I added the condition in html to no avail
{% if request.user.is_authenticated %}
<a href="{% url 'company:bookmark' slug=company.slug %}"
value="{{ company.slug }}" type="submit" class="btn_1 full-width outline wishlist">
<i class="icon_heart"></i> Add to Favourite
</a>
{% endif %}
I even tried to add id to view like this
model.bookmark.remove(request.user.id)
it bring another error:
AttributeError at
'int' object has no attribute '_state'
Here is model
class Company(models.Model):
name = models.CharField(max_length=120, help_text='Name of your company', )
slug = models.SlugField(unique=True, blank=True, null=True)
bookmark = GenericRelation(Bookmark, related_query_name='company_bookmark')
def __str__(self):
return self.name
def save(self, *args, **kwargs):
slug = slugify(self.name)
self.slug = slug
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('company:detail', kwargs={'slug': self.slug})
class Bookmark(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
and Error
Traceback:
File "C:\Users\postgres\desktop\job\env\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\postgres\desktop\job\env\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = self.process_exception_by_middleware(e, request)
File "C:\Users\postgres\desktop\job\env\lib\site-packages\django\core\handlers\base.py" in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\postgres\desktop\job\env\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
21. return view_func(request, *args, **kwargs)
File "C:\Users\postgres\desktop\biz\src\bookmarks\views.py" in company_bookmark
18. model.bookmark.add(request.user)
File "C:\Users\postgres\desktop\job\env\lib\site-packages\django\contrib\contenttypes\fields.py" in add
598. check_and_update_obj(obj)
File "C:\Users\postgres\desktop\job\env\lib\site-packages\django\contrib\contenttypes\fields.py" in check_and_update_obj
585. self.model._meta.object_name, obj
Exception Type: TypeError at /company/inceptor-kenya/bookmark
Exception Value: 'Bookmark' instance expected, got <SimpleLazyObject: <User: Gracelynn>>
If I can get help I would be much grateful. Thanks in advance.
The error is raised because you need to add a Bookmark
instance and not an User
instance to model.bookmark
(where model
is a Company
instance).
Your code:
if model.bookmark.filter(id=user.id).exists():
model.bookmark.remove(request.user)
else:
model.bookmark.add(request.user)
That could be reworked to something like this, for example:
# search bookmarks of this 'Company' with this 'user'
bookmark = model.bookmark.filter(user=user).first()
if bookmark is not None:
bookmark.delete()
else:
bookmark = Bookmark()
bookmark.user = request.user
bookmark.content_object = model
bookmark.save()