Cosmin
Cosmin

Reputation: 585

How to return single object in a Django model and view

I would like to return a very basic, single paragraph from a model but I don't know how or which is the best approach. It's a simple description textField (maindescription) that I would like to be able to change in the future instead of hard-coding it. It has to be simple way but I just could find a good example. Would appreciate any help on how to properly write the view and retrieve it in the template.

model.py

from autoslug import AutoSlugField
from model_utils.models import TimeStampedModel
from time import strftime, gmtime
# Receive the pre_delete signal and delete the file associated with the model instance.
from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver

class Song(models.Model):
    author = models.CharField("Author", max_length=255) 
    song_name = models.CharField("Song Name", max_length=255)
    slug = AutoSlugField("Soundtrack", unique=True, always_update=False, populate_from="song_name")
    created_date = models.DateTimeField(auto_now_add=True)
    updated_date = models.DateTimeField(auto_now=True)
    audio_file = models.FileField(upload_to='mp3s/', blank=True)

    def __str__(self):
        return self.song_name

class MainDescription(models.Model):    
    main_description = models.TextField()
    slug = AutoSlugField("Main Description", unique=True, always_update=False, populate_from="main_description")
    
    def __str__(self):
        return self.main_description

view.py

from django.views.generic import ListView, DetailView
from .models import Song, MainDescription

class SongListView(ListView):
    model = Song

# Overwrite the default get_context_data function
def get_context_data(self, **kwargs):
    # Call the base implementation first to get a context
    context = super().get_context_data(**kwargs)
    # Add extra information here, like the first MainDescription Object
    context['main_description'] = MainDescription.objects.first()
    return context

admin.py

from django.contrib import admin
from .models import Song, MainDescription

admin.site.register(Song)
admin.site.register(MainDescription)

urls.py

from django.urls import path
from . import views

app_name = "music"
urlpatterns = [
    path(
        route='',
        view=views.SongListView.as_view(),
        name='list'
    ),
]

song_list.html

{% extends 'base.html' %}

{% block content %}
<div class="container">
<p>{{ main_description.main_description }}</p>
</div>
<ul class="playlist show" id="playlist">
{% for song in song_list %}
    <li audioURL="{{ song.audio_file.url }}" artist="{{ song.author }}"> {{ song.song_name }}</li>  
{% endfor %}
</ul> 
{% endblock content %}
</div>

Upvotes: 1

Views: 2325

Answers (1)

OofYeetMcGee
OofYeetMcGee

Reputation: 73

It looks like you're trying to add extra context to the SongListView

class SongListView(ListView):

   model = Song

   # Overwrite the default get_context_data function
   def get_context_data(self, **kwargs):
       # Call the base implementation first to get a context
       context = super().get_context_data(**kwargs)
       # Add extra information here, like the first MainDescription Object
       context['main_description'] = MainDescription.objects.first()
       return context

Then in your template you could do something like this

<p>{{ main_description.main_description }}</p>

For more information about that from the docs, you can find it here

Upvotes: 1

Related Questions