JackRoster
JackRoster

Reputation: 1663

Django Message Application duplication error

I created a simple messaging application where users can send each other messages. I chosen to create this message instead of using a plugin because it would freely allow me to customize the code

I created 2 functions called message and read, the message function displays all the messages and it has a check box associated with it to allow the user to delete the message object and the read function captures the primary key from the template which display all the messages and get the object and filter all the objects for that thread.

The way I keep track of the replied messages is they are related to a specific thread model. and Because each message is time stamp if 2 users kept replying to each other messages , I would show all the messages related to that conversation by filtering only the previous messages and the recent message for that conversation.

Here is the tricky problem and I am grateful for anyone who helps me

I drawn a diagram to explain my situation

This picture is the message function which displays all the picture and allow the user to delete his own message

enter image description here

This is the diagram referring the second function called read

http://s21.postimg.org/ribpiuwnb/image.jpg

class Thread(models.Model):
    subject = models.CharField(max_length=100, blank=True)
    user = models.ForeignKey(User)


class Message(models.Model):
    user = models.ForeignKey(User, related_name='sender')
    recipient = models.ForeignKey(User, related_name='recipient')
    created = models.DateTimeField(auto_now_add=True)
    body = models.CharField(max_length=1000)
    read = models.BooleanField(default=False)
    sentmessage = models.BooleanField(default=False)
    thread = models.ForeignKey(Thread)
    draft = models.BooleanField(default=False)

views

@login_required
def message(request):    
    messages = Message.objects.filter(recipient=request.user).order_by("-created")  
    person = Person.objects.get(user=request.user)
    if request.method =='POST':
        delete_list = request.POST.get('hidden_field', False)
        if delete_list:
            values = [int(i) for i in delete_list.split("~")]
            m = Message.objects.filter(pk__in=values)
            m = m.filter(recipient=request.user )
            m.delete()
            return HttpResponseRedirect(reverse('world:message'))

    return render(request,'messages.html',{'messages':messages,'person':person})


@login_required
def read(request,id):

    try:
        messages = Message.objects.get(pk=id,recipient=request.user) 
    except Message.DoesNotExist:
        return HttpResponseRedirect(reverse('world:Display'))
    messages.unread = True
    messages.save()
    if request.method =='POST':
        form = ReplyForm(request.POST)
        if form.is_valid():
            id = request.POST.get('hidden_field', False)
            try:
                messages = Message.objects.get(pk=id ,recipient=request.user)

            except Message.DoesNotExist or Thread.DOesNotExist:
                return HttpResponseRedirect(reverse('world:LoginRequest'))


            body = form.cleaned_data['body']

            Message.objects.create(user=request.user,recipient=messages.user,body=body,thread=messages.    thread,sentmessage=True,read=True)
            return HttpResponseRedirect(reverse('world:message'))

    message = Message.objects.filter(thread=messages.thread ).filter(created__lte=messages.created)
    person = Person.objects.get(user=request.user)

    initial = {}
    initial.update({'hidden_field': messages.id})
    form = ReplyForm(initial=initial)

    return render(request,'read.html',{'messages':messages,'form':form,'message':message,'person':person})

message.html

<form method="POST" >
{% csrf_token %}

{% for m in messages %}


<a class="theLink" href="{% url "world:read" m.id  %}"  >

<div class="username">{{m.user.username}}</div></a>
<div class="description">{{m.body}}</div><div id="container"> </div>
<input type="checkbox" value="{{m.id}}" class="messages id_check"  >





<input type="hidden" value="" id="hidden_field" name="hidden_field" />
<input type = "button"  id="deleteBttn" value= "Delete" class="box21"/>
{% endfor %}
</form>

</div>

read.html

{% for m in message  %}

<div class="wrapper">
<div class="user">{{m.user.username}} </div>
<div class="message">{{m.body}}</div>
</div>

{% endfor %}


<form method="POST" >{% csrf_token %}
{{form.body}}{{form.hidden_field}}
    <input type = "submit" value= "send" class="sen"/>

</form>
    <input type = "submit" value= "save" class="save"/>

If the messages are been replied back and forward and my message function displays all the unread messages and also allowing the user to delete his own message . If he delete an object related to an on going conversation , its going to effect both users because the other user won't be able to read the deleted message which which is suppose to be related to the conversation . How can I solve this?

Thank you

Upvotes: 1

Views: 114

Answers (2)

Austin Phillips
Austin Phillips

Reputation: 15776

If I understand your question correctly, you want the originator of a message to be able to delete a message, but for a recipient to still be able to view that message if it hasn't yet been read?

So, instead of deleting the message when the originator hits the delete button, just have the delete mark the message has having been deleted. eg Add another field to your Message.

is_deleted = models.BooleanField(default=False)

The originator's read function would then filter on is_deleted and not display those messages. The recipient wouldn't filter on is_deleted and so continue to see the messages. You would then have to decide on a policy to purge messages from the data store that are marked is_deleted. eg. Perhaps once the message has been read by the recipient it can be automatically deleted.

You already have quite a few variables keeping track of a messages state. Perhaps it makes sense to collapse the message state to fewer enumerated type values.

Upvotes: 1

Jorge Leitao
Jorge Leitao

Reputation: 20163

Django messages is not suitable for what you are doing because it is based on cookies or sessions, not on users. So, messages are not stored between sessions.

From what I understood, now if someone deletes the message, it is deleted from the database and thus becomes unreadable to anyone else, which you don't want.

I will put your problem in more simple terms:

You have three models, user thread and message. Each user has a set of threads, and each thread has a set of messages. Each message has a sender and a recipient.

Now, each message has a set of own attributes (e.g. draft, body) and a set of attributes of the relationship between itself and the sender or recipient (e.g. "read" is not an attribute of the message itself, it is an attribute of the relationship between recipient and message ("the recipient has read the message")).

What you want now is also an attribute on the relationship between the sender and the message ("the sender deleted the message").

Like you did with "read", you should have two attributes:

is_deleted_by_sender = models.BooleanField(default=False)
is_deleted_by_recipient = models.BooleanField(default=False)

In sender/recipient messages' view, you check whether that user deleted the message or not. If he deleted the message, it no longer appears on its inbox. However, because the message still exists, the recipient/sender (notice the order) can still read it.

Messages that are deleted by both sender and recipient can be deleted from the database. Thus, either a scheduled job or after a deletion of one of the sides (sender and recipient) can trigger the message deletion from the database.

This approach is actually a simplified version of a more complex approach on which you want to define a set of attributes of the relationship of two models (in this case user and message), which can be made in Django using through.

Upvotes: 1

Related Questions