Search code examples
pythonflaskrate

How to convert likes number to percents , Flask?


I have a small problem, which is, i want to convert the number of the client likes to a percents inside the admin panel , the maximum float number is up to 5.0 so he got the 5 stars and downward tell 0.0 if no likes has been founded .

Here is my model.py:

appointment_upvotes = db.Table('appointment_upvotes',
    db.Column('appointment_id', db.Integer, db.ForeignKey('appointment.id')),
    db.Column('rate_appo_id', db.Integer, db.ForeignKey('rate_appo.id'))
)

class Appointment(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    start_time = db.Column(db.Integer(), nullable=False)
    end_time = db.Column(db.Integer(), nullable=False)
    timezone = db.Column(db.String(TIMEZONE_LEN_MAX), nullable=False)
    note = db.Column(db.String())
    status = db.Column(db.Boolean(), default=False)

    is_accepted = db.Column(db.Boolean(), default=False)
    is_not_accepted = db.Column(db.Boolean(), default=True)

    client_id = db.Column(db.Integer(), db.ForeignKey('client.id'))
    user_id = db.Column(db.Integer(), db.ForeignKey('user.id'))
    service_id = db.Column(db.Integer(), db.ForeignKey('service.id'))

    rates = db.relationship('RateAppo', backref='appointment', lazy='dynamic')

class RateAppo(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    rate_punctuality = db.Column(db.Integer(), default=0)
    rate_nonconf = db.Column(db.Integer(), default=0)
    rate_solvency = db.Column(db.Integer(), default=0)
    text = db.Column(db.Text(), default=None)

    appo_id = db.Column(db.Integer(), db.ForeignKey('appointment.id'))

    def __repr__(self):
        return "Comment: {}".format(self.text)[0:15]

    def has_voted(self, appointment_id):
        select_votes = appointment_upvotes.select(
                db.and_(
                    appointment_upvotes.c.appointment_id == appointment_id,
                    appointment_upvotes.c.rate_appo_id == self.id
                )
        )
        rs = db.engine.execute(select_votes)
        return False if rs.rowcount == 0 else True

    def vote(self, appointment_id, typevote):
        already_voted = self.has_voted(appointment_id)
        vote_status = None
        if not already_voted:
            if typevote == 'rate_punctuality':
                db.engine.execute(
                appointment_upvotes.insert(),
                    appointment_id = appointment_id,
                    rate_appo_id = self.id
                )
                self.rate_punctuality = self.rate_punctuality + 1
                vote_status = True
            elif typevote == 'rate_nonconf':
                db.engine.execute(
                appointment_upvotes.insert(),
                    appointment_id = appointment_id,
                    rate_appo_id = self.id
                )
                self.rate_nonconf = self.rate_nonconf + 1
                vote_status = True
            else:
                db.engine.execute(
                appointment_upvotes.insert(),
                    appointment_id = appointment_id,
                    rate_appo_id = self.id
                )
                self.rate_solvency = self.rate_solvency + 1
                vote_status = True
        db.session.commit()
        return vote_status

Inside the Admin panel the rate will be looks like this for instance:

Average Rating: 4.5

doesn't matter how many likes he got, lets say he got 100 likes, i don't want to show them by count, just need to get the value up to marks 5.0

Another thing i forgot to mention, maybe inside my jinja template i can make it work ??

Here is an example :

Punctuality : 100 likes in percent maybe it will be 4.52

Solvency: 63 in percent it will be maybe 3.23

so in Punctuality there will be 4 stars, and in Solvency will be 3 stars and so on .

Last thing is to show a full statistics of all these likes in one line , for example inside my panel i will get something like this :

click me to see an example

So inside my templates i can type something like this:

<div class="col-sm-8"><h2>Average Rating: <strong> {{ "%.2f" % user.rate_appo.count }} </strong></h2>
    <div class="table-responsive">
    <table class="table table-striped text-center">
      <thead>
        <tr>
          <th class="text-center">Punctuality</th>
          <th class="text-center">Non-Conflict</th>
          <th class="text-center">Solvency</th>



        </tr>
      </thead>
      <tbody>
        <tr>
          <td>{{ "%.2f" % user.rate_appo.rate_punctuality.count}} </td>
          <td>{{ "%.2f" % user.rate_appo.rate_nonconf.count}} </td>
          <td>{{ "%.2f" % user.rate_appo.rate_solvency.count}} </td>


        </tr>



      </tbody>
    </table>
</div>

Am really not sure of what i typed above, i used the %.2f just to simplify the example to be more clear for all of you .

Eventually, its a project that am working in and please any suggestions would be tons appreciated :) .


Solution

  • I couldn't find out which is the "count of likes" in your models, but I think your problem is "converting a number into another format in flask-Admin panel".

    If so, this might help:

    An example of Custom forms - flask-Admin. It converted file path into HTML tag <img> by using customized model view.

    here is the key code:

    https://github.com/flask-admin/flask-admin/blob/master/examples/forms/app.py#L110

    EDIT :

    Assume that there is a python function named convertLikes could convert likes number into stars number, like: convertLikes(100) will return 4.52. Then define it as a filter of jinja2, and replace your code:

    <td>{{ "%.2f" % user.rate_appo.rate_punctuality.count}} </td>
    

    with:

    <td>{{ user.rate_appo.rate_punctuality.count | convertLikes }} </td>
    

    the filter syntax will invoke convertLikes(user.rate_appo.rate_punctuality.count) and return the stars number into <td> tag.

    For example:

    Define a filter function in python:

    def convertLikes(count):
        # do the convertion
        return stars_number
    

    Register it on the template environment:

    app = Flask(__name__)
    app.jinja_env.filters['convertLikes'] = convertLikes
    

    Use it in jinja2 template:

    <td>{{ user.rate_appo.rate_punctuality.count | convertLikes }} </td>