3

I'm totally new to Stack Overflow and pretty new to Django/Python. I don't have much background in coding (started learning python less than a month ago) but I wanted to learn it and give it a try.

I know HTML and CSS enough to get what I want done, but Python/Django, that's still uncharted territory for me.

So far, I have a pretty basic website, and I'm trying to implement a multi-part 5-star rating system that's customizable and works with my database.

So here's my model:

class listing(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
title = models.CharField(max_length = 100, default="Class Title")
slug = models.SlugField(unique=True)
draft = models.BooleanField(default=False)
publish = models.DateField(auto_now=False, auto_now_add=False)
description = models.TextField(default="Class Description")
prerequisite = models.TextField(default="Class Prerequisites")
university = models.CharField(max_length = 100, default="Choose A University")
department = models.CharField(max_length = 100, default="Choose A Department")
last_updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
image = models.FileField(
    upload_to=upload_location,
    null=True, 
    blank=True)


def __str__(self):
    return self.title


def get_absolute_url(self):
    return reverse("listings:detail", kwargs={"slug": self.slug})

Basically, I want to have the ability to give users the option to rate each individual class based on 4 custom criteria that I define. So for example, difficulty_rating, workload_rating, book_rating, attendance_rating.

I would ideally like to have this done where the user can input their decision on a 5-star rating system, that I can customize to make the stars look how I want them to look.

Ideally, in a best case scenario, I'd like it to look like this https://codepen.io/anon/pen/JyZGqd

And I'd like that user decision to be sent to my database, to be then calculated as an average, and then displayed back on my listing_detail view as an integer that I can customize with CSS as well (a little confused on how to do that too).

Here's my listing_detail view:

def listings_detail(request, slug=None):
instance = get_object_or_404(listing, slug=slug)
share_string = quote(instance.description)
context = {
    "title": "Detail",
    "instance": instance,
    "share_string": share_string,

}
return render(request, "class_page.html", context)

Keep in mind I'm still very much a beginner! I'm trying my best to understand as much as I can with Django and Python.

What would be the best way to achieve a multi-part 5-star rating system that's fully customizable in design?

Thank you for your time and help!

Darius Mandres
  • 778
  • 1
  • 13
  • 31

1 Answers1

2

There a lot to do so i'm not gonna write you all the codes but i'll try to guide you on the right way:

as you said you are able to make something like start rating with css and html so no problem there.

for sending the rating to django you need to follow these steps:

1 - if you want the data of which users rated and whats their rating you need a new model for that with the fields you need (user, what they rated and if there is more than one to rate then a field for each of them. like difficulty_rate and etc + a field to point to the listing or anything else which this rating row is for. you can do this by using relationship fields.

Examples of model relationship API usage | Django documentation

2 - in you template you need javascript to send the rating to django (you can do it without javascript but you should make a form and design it the way you want it to be)

if you are using javascript then you should listen for clicks and send the user and the rating to django. this way you need Django REST framework to help you. you send the data using javascript and ajax and then you get the data on your views. this is the harder way but a better way for users to submit their ratings.

Django REST framework

but if you don't want to use javascript or ajax you can use forms. you make a form and design it and you add a submit button. after than all the data will be available in you views like a normal form and you can save the data in database and do the calculation however you like.

your rating model will be something like this:

class Rate(models.Model):
    listing = models.ForeignKey(listing)
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    dif_rate = models.IntegerField(null=True, blank=True)
    other_rate = models.IntegerField(null=True, blank=True)
    ...

your view will be different based on what way you want to do it but if you use forms which is the easy way it would be something like this:

......
if request.method == 'POST':
    # take care of instance
    form = RateForm(request.POST, instance=your-listing-instance)
    if form.is_valid():
        rate = form.save(commit=False)
        # adding the user here.
        rate.user = request.user
        rate.save()
 ......

and your forms.py:

class RateForm(forms.ModelForm):
    class Meta:
        model = Rate
        fields = ('dif_rate', 'other_rate')
Navid Zarepak
  • 4,148
  • 1
  • 12
  • 26
  • hey thanks for the reply! I just had a few questions regarding the form way of doing things, if you don't mind. I've tried this method and I've successfully created a form. When I go to the html template for that respective form I can see my choices for difficulty_rating, etc.. I can select from 1 to 5 let's say with a drop down menu. That's fine and then that information is sent to the database, which is great. But how do I make that dropdown menu show as stars that are customizable by css? That's the part I'm not clear on. And also perhaps how to calculate the average afterwards? – Darius Mandres Aug 23 '17 at 15:13
  • the designing part i can't help you much. i'm a really bad designer (:D) and its not in my expertise but i think you can use any other inputs which makes your life easier to design a star-like rating system. like radio box? then you have to work with javascript for a bit and in your view you just have to check which radio box has been used. keep in mind; you don't have to work with form to do all the things for you. you can extract the inputs like this: `rate = request.POST.get('your-input-name')` which gives you the value of that input and you can save them manually or do your calculating – Navid Zarepak Aug 23 '17 at 16:30
  • Digging up an old post. Wondering if you managed to make you rating work and if you could share what you did. I'm trying to do something similar and just like you I am not clear how to translate the drop down form into radio buttons. – PhilM Sep 05 '22 at 19:48