Search code examples
pythonflaskjinja2peeweeflask-peewee

Encoding id and storing it as a unique code and store in table on creation of row


Essentially, I'm trying to eliminate the need to show the id of a 'listing' to the user. I'm using Hashids to encode the automatically created id as a unique code.

To show a single listing, I've been currently doing this:

@app.route('/listing/<uniqueHash>')
def listing(uniqueHash):
    a = hashids.decode(uniqueHash)
    listing = models.Listing.select().where( models.Listing.id == a ).get()
    uniqueHash = hashids.encode(listing.id)
    return render_template("test1.html", listing = listing, uniqueHash = uniqueHash)

and this works fine for a single listing. However, if I wanted to display multiple listings like this:

@app.route('/')
def index():
    listings = models.Listing.select().limit(100)
    return render_template("test.html", listings = listings)

I then can't provide the unique id for every listing to the jinja2 template (and don't see a way to encode/decode ids in the jinja template itself...is there?)

I'd ultimately like to store the unique code in the database, however am confused as to how to create the hashid - based off the id of the listing - when I'm creating that listing itself and don't know the id.

I'm currently creating a listing like this:

form = request.form
models.Listing.create(
    title = form['title'],
    description = form['description'],
    price = form['price']
)

I'm planning later to use this with WTForms for validation.

How am I best to include the unique code in the creation of a listing without knowing the id itself???

Any help is greatly appreciated!!! 🙏 🙏 🙏


Solution

  • Within your Listing model, you could define a function such as:

    def getHashId(self):
        return hashid.encode(self.id)
    

    Now, anywhere in your Jinja2 template that you are using an instance of Listing, you can call listing.getHashId() to return the hashid matching the listing in question. This way, you don't need to store the hashid in the database either.

    You could then simplify your listing function to something like this:

    @app.route('/listing/<uniqueHash>')
    def listing(uniqueHash):
        try:
            listing = models.Listing.select().where(models.Listing.id == hashid.decode(uniqueHash).get())
            return render_template("test1.html", listing=listing)
        except:
            #Listing with that uniqueHash does not exist