0

I am working on a Django (v1.11.0) project and I have two models called Song that contain users songs and GenericSong that contain administration songs.

class Song(models.Model):
    album = models.ForeignKey(Album, on_delete=models.CASCADE)
    song_title = models.CharField(max_length=250)
    audio_file = models.FileField()
    is_favorite = models.BooleanField(default=False)

    def __str__(self):
        return self.song_title


class GenericSong(models.Model):
    album = models.ForeignKey(GenericAlbum, on_delete=models.CASCADE)
    song_title = models.CharField(max_length=250)
    audio_file = models.FileField(default='')
    is_favorite = models.BooleanField(default=False)

    def __str__(self):
        return self.song_title

I want to list all the songs in the database which contain users and administration songs, the problem is, I want to list that with a pagination. I did this for a page that contain only users songs using this view, which is working just fine :

@login_required()
def songs(request, filter_by=None):

    users_songs = Song.objects.filter(album__user=request.user)
    page = request.GET.get('page', 1)
    if filter_by == 'favorites':
        users_songs = users_songs.filter(is_favorite=True)

    paginator = Paginator(users_songs, 10)
    try:
        songs_page = paginator.page(page)
    except PageNotAnInteger:
        songs_page = paginator.page(1)
    except EmptyPage:
        songs_page = paginator.page(paginator.num_pages)
    return render(request, 'music/songs.html', {
        'song_list': songs_page,
        'filter_by': filter_by,
    })

But in the second view, I don't know how to make song and genericsong in one variable to make tha pagination, here is the all songs view that I want to make changes to it :

@login_required()
def all_songs(request, filter_by=None):

    users_songs = Song.objects.all()
    generic_songs = GenericSong.objects.all()

    return render(request, 'music/songs.html', {
            'song_list_all': users_songs,
            'generic_song_list': generic_songs,
            'filter_by': filter_by,
    })
eliadesign
  • 15
  • 1
  • 7

1 Answers1

1

You have two identical models. Combine them into one and add type:

class Song(models.Model):
    album = models.ForeignKey(Album, on_delete=models.CASCADE)
    song_title = models.CharField(max_length=250)
    audio_file = models.FileField()
    is_favorite = models.BooleanField(default=False)

    types = models.PositiveIntegerField(choices=SONG_TYPES, blank=True, null=True, default=1)

    def __str__(self):
        return self.song_title

Then user Paginator as usual with filtering

admin_songs = Song.object.filter(type=1)
other_songs = Song.object.filter(type=2)
Alexander Tyapkov
  • 4,837
  • 5
  • 39
  • 65
  • I can't do that, because I should change the whole code of my wesite, and I did almost 99% of the work, is their any other method to do this without changing models ? – eliadesign Oct 26 '17 at 23:33
  • 1
    Here is another solution which will work https://stackoverflow.com/a/15597480/709897 Paginator accepts lists so you can easily combine two models into list and sort it by common attribute. – Alexander Tyapkov Oct 26 '17 at 23:40
  • @eliadesign You'd probably be better off fixing your data model than using hacks. –  Oct 26 '17 at 23:53