'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 |