pythonhtmldjangodjango-admindjango-admin-actions

Django admin list_display of different data types with null


I know I explained the title poorly, look I have a simple chat app where users can send text/audio/video/image and for me to render those messages I have a method that checks the type of the message and renders it accordingly if it was text then i will set safe to False in my template, else I will display what the function will give me which is an HTML code

What I really want is: Admin panel giving me message text[:50] if it was text, if it was audio then i can have an audio preview for it, if it was image or video or file then it will give me the url. Is there anyway to do so?

here are my files so you can get a better understanding of what I'm saying:

models.py:

class Message(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    room = models.ForeignKey(Room, on_delete=models.CASCADE)

    text = models.TextField(blank=True, null=True)
    video = models.FileField(upload_to="chat/room/vid", blank=True, null=True)
    image = models.FileField(upload_to="chat/room/img", blank=True, null=True)
    file = models.FileField(upload_to="chat/room/file", blank=True, null=True)
    audio = models.FileField(upload_to="chat/room/aud", blank=True, null=True)

    is_read = models.BooleanField(default=False)
    date = models.DateTimeField(auto_now_add=True)

    def content(self):
        if self.text:
            return self.text
        elif self.video:
            return f"""
            <video width="320" height="240" controls>
                        <source src="{self.video.url}" type="video/mp4">
                        <source src="{self.video.url}" type="video/mov">
                        <source src="{self.video.url}" type="video/wmv">
                        <source src="{self.video.url}" type="video/avi">
                        <source src="{self.video.url}" type="video/avchd">
                    Your browser does not support the video tag.
                    </video> 
            """
        elif self.image:
            return f'<img src="{self.image.url}" alt="">'
        elif self.file:
            return f'<p><a href="{self.file.url}" download><i class="fas fa-download"></i> {self.filename()}</a></p>'
        elif self.audio:
            return f"""
            <audio controls>
                        <source src="{self.audio.url}" type="audio/pcm">
                        <source src="{self.audio.url}" type="audio/wav">
                        <source src="{self.audio.url}" type="audio/aiff">
                            <source src="{self.audio.url}" type="audio/mp3">
                                <source src="{self.audio.url}" type="audio/aac">
                                <source src="{self.audio.url}" type="audio/ogg">
                                <source src="{self.audio.url}" type="audio/flac">
                                <source src="{self.audio.url}" type="audio/wma">
                    Your browser does not support the audio element.
                    </audio>
            """
        else:
            return self.text

And here is my HTML template:

{% for room_message in room_messages %}
    {% if room_message.text %}
    <p>{{ room_message.content }}</p>
    {% else %}
    {{ room_message.content|safe }}<br>
    {% endif %}
{% endfor %}

Now where is the problem? at my admin panel if there wasn't a text it will give me "-" for the message content

My admin.py:

from django.contrib import admin
from .models import Room, Area, Message


admin.site.register(Room)
admin.site.register(Area)
@admin.register(Message)
class MessageAdmin(admin.ModelAdmin):
    '''Admin View for Message'''

    list_display = ('user','room', 'user', 'is_read', 'text')
    readonly_fields = ('date',)

Solution

  • You could try to have a function called get_content() and include that in list_display like

    list_display = ('user','room', 'user', 'is_read', 'get_content')
    

    Have this function inside your class

    def get_content(self, obj):
        if obj.text:
            return obj.text
        elif obj.video:
            return obj.video.url
        elif obj.image:
            return obj.image.url
        elif obj.file:
            return obj.file.url
        elif obj.audio:
            return obj.audio.url
    

    This method must be inside your ModelAdmin class.