'How to mention users using @ in django

I have been working on a project on django and it is very similar to instagram and twitter, one of the functions it needs to have is to mention users using "@" in text fields. I have been investigation a little while now on how I can do that in django and I have found litteraly nothing except some libraries like django-mentions which I don't understand how it works but I have also found that this is possible using react but I don't know if it is possible to implement react to an almost finished django project. How can this function work? Should I use react or any javascript?

models.py

class Post(models.Model):
    text = models.CharField(max_length=200)
    user = models.ForeignKey(User, related_name='imageuser', on_delete=models.CASCADE, default='username')

views.py (upload view contains the form that stores the post to later display it and main view displays the uploaded post)

def upload(request):

    if request.method == 'POST':
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.user = request.user
            instance.save()
            return redirect('home')
            print('succesfully uploded')

    else:
        form = PostForm()
        print('didnt upload')
    return render(request, 'home.html', {'form': form})

def main(request):
    contents = Post.objects.all()

    context = {
        "contents": contents,
    }
    print("nice2")
    return render(request, 'home.html', context)

forms.py

class PostForm(forms.ModelForm):

    class Meta:
        model = Post
        fields = ('text')
        exclude = ['user']

html (form that uploads a post with text in which the user can type @mentions)

<form method="post" action="{% url 'upload' %}" enctype="multipart/form-data">        
    {% csrf_token %}
    <input type="text" name="text" placeholder="Add a comment..." required="" id="id_text">
    <button class="submit-button" type="submit">Save</button>
</form>

html (Here is where the post is displayed)

{% for content in contents %}
    {% if contents %}
        <div class="element"><p>{{ content.text }}</p></div>
    {% endif %}
{% endfor %}

Please if you have any questions please let me know, rememnber that any idea helps.



Solution 1:[1]

You can actually build your custom-template tag to check for the @(pattern) in whatever field you want and in the custom tag function only you can check whether the user exists or not if exists then do whatever you want(like creating notification or linking to mentioned user profile)

######something like this #######

  @register.filter(name='mention', is_safe=True)
  @stringfilter
  def mention(value):
     res = ""
     my_list = value.split()
     for i in my_list:
        if i[0] == '@':
            try:
              stng = i[1:]
              user = User.objects.get(username = stng)
              if user:
                 profile_link = user.userprofile.get_absolute_url()
                 i = f"<a href='{profile_link}'>{i}</a>"

            except User.DoesNotExist:
            print("Could not get the data")

      res = res + i + ' '
    
   return res

however, to be more efficient u can also use regex to find the pattern. Now add the tag named "mention" to your HTML and don't forget to load the tag

Solution 2:[2]

I found that post helps in the idea of using martor text editor but it is not that hard.

In my app, I have an accounts app that contains Profile model to redirect the mention link @[user] to the profile of the user

models.py

from django.contrib.auth.models import User
class Profile(models.Model):
  user= models.OneToOneField(User, on_delete=models.CASCADE)

urls.py

path('profile/<str:user>/',views.profile, name='profile'),

views.py

from . models import Profile
def profile(request,user):
the_user= User.objects.get(username=user)
profile= Profile.objects.get(user=the_user)
return render(request, 'profiles/profile.html',{'profile': profile})

settings.py

MARTOR_MARKDOWN_BASE_MENTION_URL = '/accounts/profile/'

then the editor continues with the user on mention @[user] /accounts/profile/user

Solution 3:[3]

make a custom template tag and try this

from django import template
from django.template.defaultfilters import stringfilter
import re
register = template.Library()

@register.filter(name='usermention', is_safe=True)
@stringfilter
def usermention(value):
    value = re.sub(r'@(\w+)', r'<a href="/\1/">@\1</a>', value)
    return value

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Anshu Pal
Solution 2 Mohab Mohamed Gamal
Solution 3 Arpit Soni