Стилизация .IntegerField(), чтобы сделать его системой звездного рейтинга?

Моя конечная цель — получить 5-звездочную рейтинговую систему для моего веб-сайта в Django. Я приближаюсь к нему с формой, которая связана с моей моделью.

Вот модель для моего обзора:

class review(models.Model):
ONE_TO_FIVE_RATING_CHOICES = (
    (1, '1'),
    (2, '2'),
    (3, '3'),
    (4, '4'),
    (5, '5'),
)
BOOK_RATING_CHOICES = (
    (1, '$'),
    (2, '$$'),
    (3, '$$$'),
    (4, '$$$$'),

)
ATTENDANCE_RATING_CHOICES = (
    (1, 'Not Required'),
    (2, 'Required'),


)
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=0)
course = models.ForeignKey(listing)
slug = models.SlugField(unique=True, default=None)
pub_date = models.DateTimeField('date published')
user_name = models.CharField(max_length=100)
title = models.CharField(max_length=140)
review_content = models.TextField()
difficulty_rating = models.IntegerField(choices=ONE_TO_FIVE_RATING_CHOICES)
workload_rating = models.IntegerField(choices=ONE_TO_FIVE_RATING_CHOICES)
book_rating = models.IntegerField(choices=BOOK_RATING_CHOICES)
attendance_rating = models.IntegerField(choices=ATTENDANCE_RATING_CHOICES)

И вот форма:

class ReviewForm(forms.ModelForm):

class Meta:
    model = review
    fields = [

    'difficulty_rating',
    'workload_rating',
    'book_rating',
    'attendance_rating',
    'title',
    'review_content',



    ]

Мой вопрос в том, как мне стилизовать это с помощью CSS? Я хочу преобразовать это в радио-вводы, которые затем я могу покрыть значками звезд (от FontAwesome) и при этом сохранить функциональность возможности отправки этих вводов в мою базу данных.

Есть ли простой способ? Или это сложное дело?


person Darius Mandres    schedule 23.08.2017    source источник
comment
Даже если вы действительно хотите реализовать свой собственный, это может помочь: github.com/wildfish/django- рейтинги   -  person Paulo Almeida    schedule 23.08.2017
comment
Я изучил это, правда в том, что я очень новичок в Django/Python и не мог понять, как это реализовать. Я установил его просто отлично, но когда дело доходит до его использования, я получаю эту ошибку: Недопустимый тег блока в строке 33: «рейтинги», ожидаемый «конечный блок». Вы забыли зарегистрироваться или загрузить этот тег? Эта ошибка возникает сразу после добавления {% ratings object %} в мой шаблон. Я не слишком уверен, как это сделать.   -  person Darius Mandres    schedule 23.08.2017
comment
Может быть, вы забыли включить {% load ratings %} вверху шаблона? Это то, что сообщает обработчику шаблонов, что теги шаблона рейтингового приложения существуют.   -  person Paulo Almeida    schedule 23.08.2017
comment
Нет, это там. Я поместил его вверху моего base.html, что дало мне указанную выше ошибку, но если я поместил его на свой class_page.html, это дает мне объект «str», не имеет атрибута «_meta». ошибка. редактировать: неважно, мне пришлось вместо этого поставить {% ratings instance %}, и теперь это работает! Просто нужно выяснить остальную часть системы звездного рейтинга и как заставить ее работать с моей базой данных.   -  person Darius Mandres    schedule 23.08.2017
comment
Возможно, у вас это не сработает, потому что оно как бы связывает модель с рейтингом, а вы хотите связать несколько полей модели. Однако это может помочь вам с реализацией, особенно если вы посмотрите на виджет.   -  person Paulo Almeida    schedule 23.08.2017


Ответы (1)


По сути, все, что вам нужно сделать, можно разбить на следующие шаги:

  1. Скройте радиополя, установив свойство CSS display: none;.
  2. Показывать звезды вместо радиополей.
  3. Установите значение рейтинга для каждой звезды. Например. Первая звезда должна иметь значение рейтинга 1, вторая звезда должна иметь значение 2 и так далее.
  4. Установите целевое значение для имени соответствующего радиополя.
  5. Когда пользователь нажимает на звездочку, возьмите ее значение рейтинга и проверьте соответствующее целевое поле радио с помощью JavaScript.

ПОСМОТРЕТЬ ДЕМО.

HTML:

Первое, что нужно отметить, это то, что вы должны установить значение рейтинга и целевой радиовход для каждой звезды. Таким образом, если щелкнуть звезду, вы берете ее значение рейтинга и проверяете целевой радиовход.

Итак, звезда должна выглядеть так:

<i class="rating-star" data-rating="1" data-target="difficulty_rating"></i>

Если вы создаете звездочку для workload_rating, вам нужно изменить ее значение data-target:

<i class="rating-star" data-rating="1" data-target="workload_rating"></i>

Вы можете повторить это для других полей рейтинга.

Пример кода для звездочек (скопируйте и вставьте следующий код туда, где вы хотите отобразить звездочки):

<!-- Stars for difficulty_rating -->
<div class="rating">
    <!-- The stars must be in reverse order of rating value -->
    <i class="rating-star" data-rating="5" data-target="difficulty_rating"></i>
    <i class="rating-star" data-rating="4" data-target="difficulty_rating"></i>
    <i class="rating-star" data-rating="3" data-target="difficulty_rating"></i>
    <i class="rating-star" data-rating="2" data-target="difficulty_rating"></i>
    <i class="rating-star" data-rating="1" data-target="difficulty_rating"></i>
</div>

<!-- Stars for workload_rating -->
<div class="rating">
    <!-- The stars must be in reverse order of rating value -->
    <i class="rating-star" data-rating="5" data-target="workload_rating"></i>
    <i class="rating-star" data-rating="4" data-target="workload_rating"></i>
    <i class="rating-star" data-rating="3" data-target="workload_rating"></i>
    <i class="rating-star" data-rating="2" data-target="workload_rating"></i>
    <i class="rating-star" data-rating="1" data-target="workload_rating"></i>
</div>

CSS:

Добавьте это в свою таблицу стилей CSS:

.rating {
  overflow: hidden;
  display: table;
  font-size: 20px;
  color: #FFCA00;
  font-style: normal;
}

.rating-star {
  padding: 0 5px;
  margin: 0;
  cursor: pointer;
  display: block;
  float: right;
}

.rating-star:after {
  position: relative;
  font-family: FontAwesome;
  content: '\f006';
}

.rating-star.checked ~ .rating-star:after,
.rating-star.checked:after {
  content: '\f005';
}

.rating:hover .rating-star:after {
  content: '\f006';
}

.rating-star:hover ~ .rating-star:after,
.rating-star:hover:after {
  content: '\f005' !important;
}

JavaScript:

Я использовал jQuery, чтобы упростить часть JavaScript.

Вставьте следующий код перед тем, как тег </body> заканчивается в вашем шаблоне:

<!-- Include jquery -->
<!-- this requires an internet connection. but you can download jquery and put it in your static folder and link it from there -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<!-- JS code for updating rating values -->
<script>
    $('.rating-star').on('click', function() {
        $(this).parents('.rating').find('.rating-star').removeClass('checked'); // uncheck previously checked star

        $(this).addClass('checked'); // check currently selected star

        var ratingValue = $(this).attr('data-rating'); // get rating value
        var ratingTarget = $(this).attr('data-target');

        // set the rating value to corresponding target radio input
        $('input[name="' + ratingTarget + '"][value="' + ratingValue + '"]').prop('checked', true);
    });
</script>
person xyres    schedule 23.08.2017
comment
Спасибо за комментарий! так что это работает, но это никак не связано с моей моделью, не так ли? В идеале я хотел бы, чтобы любые входные данные, выбранные пользователем, записывались как данные для конкретного экземпляра моей модели, чтобы затем я мог отображать среднее значение этих оценок на той же странице. Как бы я это сделал? потому что, насколько я понимаю, это просто создание совершенно новой рейтинговой системы, и пока, основываясь на коде, я не вижу, чтобы он каким-либо образом был связан с моей моделью. - person Darius Mandres; 23.08.2017
comment
@dmandres Вы уже создали форму django? Все, что вам нужно сделать, это отобразить эту форму в ваших шаблонах и скрыть входные данные. Я думал, вы все это реализовали. Если нет, вам нужно прочитать документы django о том, как связать форму с моделью и сохранить данные. - person xyres; 24.08.2017
comment
У меня уже есть форма! Но для отображения этой формы в моих шаблонах я использую {{ form.as_p }}. Что блокирует меня в стиле по умолчанию для указанной формы, я не понимаю, как я могу скрыть входные данные/заменить их звездочками? - person Darius Mandres; 25.08.2017