How to set Model property, toggle a boolean in Django query?
Clash Royale CLAN TAG#URR8PPP
How to set Model property, toggle a boolean in Django query?
Is it possible in my Detail view below, to set the boolean within a model to be false ?
I looked through the django documentation (queryset) for something like a .set()
method for this, it seems to exist but not applicable to this particular case.
How can I toggle the unread
boolean in my Models.py
, through my view ?
.set()
unread
Models.py
Also, what am I misunderstanding here and what is the better/appropriate way to do this ?
Models.py:
class Message(models.Model):
recipient = models.ForeignKey(CustomUser, on_delete = models.CASCADE,related_name = 'recipient',null = True)
sender = models.ManyToManyField(CustomUser,related_name = 'messages')
date = models.DateTimeField(auto_now_add=True, blank=True)
subject = models.CharField(max_length = 1000, blank = True)
message = models.TextField(blank=True, null=True)
unread = models.BooleanField(default = True)
Views.py :
### Message detail class
class MessageInboxDetail(DetailView):
'''
This view lets the user view the details of a message created
'''
context_object_name = 'message_detail'
model = Message
template_name = "myInbox/message_detail.html"
def get_context_data(self, **kwargs):
context = super(MessageInboxDetail, self).get_context_data(**kwargs)
context.update(
'message_detail': Message.unread.set(False) ) # Message(unread=True/False)
return context
context['instance'].unread = False
context['instance'].save()
@WillemVanOnsem I get a linting warning : "Instance of BooleanField has no set member" Then I get a KeyError for 'instance' .
– timi95
Aug 8 at 14:24
1 Answer
1
You do not set the field of a model instance with a .set(..)
call, but by assigning to the attribute (behind the curtains, Django has patched the __get__
and __set__
functions).
.set(..)
__get__
__set__
We can thus obtain the message
object by retrieving it out of the context (with context['message_detail']
, and then change it state, and finally save the updated version to the database. For example:
message
context['message_detail']
class MessageInboxDetail(DetailView):
'''
This view lets the user view the details of a message created
'''
context_object_name = 'message_detail'
model = Message
template_name = "myInbox/message_detail.html"
def get_context_data(self, **kwargs):
context = super(MessageInboxDetail, self).get_context_data(**kwargs)
message = context['message_detail']
message.unread = False
message.save()
return context
I however do not know if it is a good idea to mark a message as read in the detail view, it can result in code duplication, which is usually not a good idea.
" I however do not know if it is a good idea to mark a message as read in the detail view, it can result in code duplication, which is usually not a good idea. " Can you explain further please ? Is there a better/simpler way to implement this feature in django ?
– timi95
Aug 8 at 14:52
@timi95: it might be better to implement a
mark_read
function in the Message
class itself. Furthermore it could happen that if the view fails (or for example the network connection of the user stops working), the message is marked read without the user actually having read the message. If you want to prevent that, an AJAX call to a view that marks messages as read might perhaps be more robust.– Willem Van Onsem
Aug 9 at 7:16
mark_read
Message
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
context['instance'].unread = False
andcontext['instance'].save()
.– Willem Van Onsem
Aug 8 at 14:10