Private Pocket using Django admin

Tormich
3 min readJul 8, 2020

--

Pocket is nice bookmark storage with many good features.

So let’s make a quick, private, free and very simple version of it. But let’s do it in the laziest way possible.

To do so we will use python — cause it’s awesome and Django — cause it comes with batteries.

We will host this project at pythonanywhere.com. It has a free tier and a nice and simple UI.

Setup the environment

To keep our labor to the minimum we will use the fact that PythonAnywhere does all the hosting related settings and creation of the Django project for us.

First, register a beginner account and verify your email.

Now, go to the “Web” tab and “Add a new web app”. Press “Next” press “Django” and then press “Python 3.8 (Django 2.2.7)”.

The project name will determine the folder name in which the Django project will be created as well as the Django project name. I’ll leave it to be “mysite”.

Press “Next” and after a few seconds, your project is ready and running.

Django app

To create a Django app we will need to open a console. To do so you should go to the “Consoles” tab and press “Bash”.

When in the console do the following:

cd mysite/ 
django-admin startapp bookmarks

This will create the application folder called “bookmarks” with all the files. Now we can go to the “Files” tab and navigate to it. Inside you will find the standard Django app files

__init__.py
admin.py
apps.py
migrations
models.py
tests.py
views.py

Our super simple application

Edit mysite/bookmarks/models.py to add the model that will store our links. We will add an "owner" field so you could share the awesomeness with your friends and family. And everybody will have there own links.

from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Link(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
url = models.URLField(max_length=1000)
title = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)

Now, to harness the builtin UI we need to add Link model to the mysite/bookmarks/admin.py

from django.contrib import admin
from django.utils.html import format_html
from .models import Link
@admin.register(Link)
class LinkAdmin(admin.ModelAdmin):
list_display = "id", "open_link", "title", "created_at"
exclude = "owner",
def open_link(self, obj: Link) -> str:
return format_html(
'<a class="button" href="{}" target="_blank">open</a>',
obj.url
)
def get_queryset(self, request):
qs = super().get_queryset(request)
qs.filter(owner_id=request.user.id) # show user only his links
def save_model(self, request, obj: Link, form, change):
# automatically add user as an owner to the links he is saving
if not obj.owner_id:
obj.owner = request.user
super().save_model(request, obj, form, change)

The last two steps are:

  • change the path to admin page (Admin UI is the main UI for us, so we will treat it as such)
  • add our application to settings.py.

First mysite/mysite/urls.py:

from django.contrib import admin
from django.urls import path
from django.utils.html import format_html
from django.urls import reverse
import os
urlpatterns = [
path('', admin.site.urls),
]
# This should be in settings.py but, Ain't Nobody Got Time For That
SITE_DOMAIN = os.environ.get("PYTHONANYWHERE_DOMAIN")
# This javascript is what will open the popup to save a link
# Some people call it bookmarklet.
POPUP_JS = f'javascript: void (window.open("https://{SITE_DOMAIN}{reverse("admin:bookmarks_link_add")}?' \
f'_to_field=id&_popup=1" + "&url=" + ' \
f'encodeURIComponent(document.location.href) + "&title=" + ' \
f'encodeURIComponent(document.title), "_blank", "resizable=yes,width=800,height=450"));'
HEADER_HTML = 'Bookmarks <a class="button colMS" href="{}" target="_blank">save</a>'# Not the most elegant way to make a button
# but the most straight forward
admin.site.site_header = format_html(HEADER_HTML, POPUP_JS)
admin.site.site_title = "Bookmarks"
Drag this “save” button to the bookmarks bar in your browser.

Now add application name to the INSTALLED_APPS list in mysite/mysite/settings.py

We did it! Congratulations!

Now go back to the bash console you have opened previously and run:

./manage makemigrations
./manage migrate

To activate all this awesomeness you need to open the “Web” tab and press the reload button.

Now open a page you want to save and click the “save” bookmarklet.

“Add link” popup appears when “save” bookmarklet is clicked.

--

--