Изначально проблема создания системы лайков / дизлайков кажется простым делом. Две кнопочки, +1 к лайкам, если нажали на первую, +1 к дизам, если на вторую. Но всплывает несколько тонкостей, которые надо учитывать.
Моё решение
Первым делом я создал таблицу для постов: автор, текст поста и так далее. Но дополнительно добавил поля лайков и дизов. Так можно сделать с любой таблицей: комментарии, фотографии или видео. При нажатии пользователем одной из кнопок "лайк / диз", значение соответствующего столбца должно расти. Но если оставлять логику в таком виде, то пользователь сможет нажимать любую из кнопок неограниченное число раз, поэтому нужно дополнительно хранить информацию о выборе каждого.
Я создал дополнительную таблицу с полями: пользователь, пост и лайк_или_дизлайк. То есть в ней мы храним каждый выбор каждого пользователя к конкретному посту. И связь у второй таблицы по ForeignKey к пользователю поставившему оценку и к оцениваемому посту.
Дальше логика такая: у пользователя есть две кнопки "Лайк" и "Дизлайк". Обрабатывает нажатие одна функция, которая принимает в качестве параметров пост, который оценивается, и строку "like" или "dislake". Дальше у нас есть 5 вариантов для действий. Мы проверяем, нажимал ли соответствующие кнопочки авторизованный пользователь, для этого выдергиваем запись из таблицы, где пользователь=request.user (авторизованный пользователь), пост=текущий пост. Если такой записи по запросу не найдено, то мы её создаём.
Но если оценка от текущего пользователя к этому посту есть, то у нас будет четыре варианта. Он уже ставил лайк и нажал по нему ещё раз, значит оценка должна исчезнуть (запись удалена), второй вариант такой же, но с дизлайком. Другие два варианта, если пользователь поменял свой выбор. Главное, не забыть поменять значение в нашей основной таблице Post.
Более подробный код можно найти на моем гитхабе, ссылку на который я оставил в предыдущей статье. Так же результат работы можно проверить в моей экспериментальной социальной сети (но придётся зарегистрироваться).
Конечно, как урок это трудно расценивать, но возможно будет полезно, как идея.)