Tutorials

Row-level Permissions in Django Admin

So you’ve started working with Django and you love the admin interface that you get for free with your models. You deploy half of your app with the admin interface and are about to release when you figure out that anyone who can modify a model can do anything with it. There is no concept of “ownership” of records!

Let me give you an example. Let’s say we’re creating a little MIS for the computer science department where each faculty member can put in his courses and record the course execution (what was done per lecture). That would be a nice application. (In fact, it’s available open source on github and that is what this tutorial is referring to.) However, the issue is that all instructors can access all the course records and there is no way of ensuring that an instructor can modify only the courses that s/he taught. This isn’t easily possible because admin doesn’t not have “row-level permissions”.

Of course, we can create them by sub-classing some of the Admin classes and modifying a couple of functions. Here’s how:

Let’s assume we have the following in our models:

class Instructor(models.Model):
    name = models.CharField(max_length=200)
    # other stuff here 

class Course(models.Model):
    course_code = models.CharField(max_length=10, default='CS')
    instructor = models.ForeignKey(Instructor)
    course_name = models.CharField(max_length=200)
    # other stuff here 

class CourseOutline(models.Model):
    course = models.OneToOneField(Course)
    objectives = models.TextField(blank=True)
    # other stuff 

And in admin.py, we have the following:

class CourseAdmin(admin.ModelAdmin):
    list_display = ('course_name', 'instructor')
    # some other stuff 

admin.site.register(Course, CourseAdmin)

class CourseOutlineAdmin(admin.ModelAdmin):
    # nothing here of importance     

admin.site.register(CourseOutline, CourseOutlineAdmin)

So, when you open the page for Course, you can see the instructors and when you open the CourseOutline, you can see the Courses. Pretty good but how do we add row-level permissions? We do this by overriding a couple of functions.

Here’s the strategy I followed:

First, create a user account for each instructor. Then, take away these user’s rights to modify Instructor objects. (You can keep stuff in Instructor Profile so that they can modify their information.)

Next, add a field to the Instructor model that binds it to a particular user. The model now becomes:

from django.contrib.auth.models import User
...

class Instructor(models.Model):
    name = models.CharField(max_length=200)
    owner = models.ForeignKey(User)
    # other stuff here 

The other models can remain the same. We only need to modify their “querysets”. Let’s open up admin.py again and modify the *Admins.

We override two functions to make CourseAdmin look like the following:

class CourseAdmin(admin.ModelAdmin):
    # whatever was here 
 
    def queryset(self, request):
        qs = super(CourseAdmin, self).queryset(request)
        if request.user.is_superuser:
            return qs 
        
        # get instructor's "owner" 
        return qs.filter(instructor__owner=request.user)
    
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "instructor" and not request.user.is_superuser:
            kwargs["queryset"] = Instructor.objects.filter(owner=request.user)
            return db_field.formfield(**kwargs)
        return super(CourseAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
    
admin.site.register(Course, CourseAdmin)

What’s that? The first function basically modifies the queryset function and makes sure that if you’re not a super user, you will see only those courses in the course list where instructor__owner=request.user i.e. your own courses.

The second function is required so that you can’t add courses that belong to other instructors. It filters the foreign key dropdown box so that only owner=request.user objects are shown in the foreign key dropdown. That is, you only see yourself in that dropdown.

We can do the same thing for CourseOutline. That is here:

class CourseOutlineAdmin(admin.ModelAdmin):
    # whatever was here 

    def queryset(self, request):
        qs = super(CourseOutlineAdmin, self).queryset(request)
        if request.user.is_superuser:
            return qs 
        
        # get instructor's "owner" 
        return qs.filter(course__instructor__owner=request.user)
    
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "course" and not request.user.is_superuser:
            kwargs["queryset"] = Course.objects.filter(instructor__owner=request.user)
            return db_field.formfield(**kwargs)
        return super(CourseAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

The only difference is that we’re now going two levels up the foreign key ladder. That’s all you need to have row-level permissions in admin. Questions?

AVL Tree in Python

I’ve been teaching “Applied Algorithms and Programming Techniques” and we just reached the topic of AVL Trees. Having taught half of the AVL tree concept, I decided to code it in python — my newest adventure. Bear in mind that I have never actually coded an AVL tree before and I’m not particularly comfortable with python. I thought it would be a good idea to experiment with both of them at the same time. So, I started up my python IDE (that’s Aptana Studio, btw) and started coding.

For the newbie programmer, the code itself may not be very useful since you can find better code online. The benefit is in being able to look at the process. You can take a look at the commits I made along the way over here on github. You can take a look at how I structured the code when I began and how I added bits and pieces. This abstraction should help in solving other problems as well. The final code (along with a rigorous unit test file) can be seen here: https://github.com/recluze/python-avl-tree

A No-nonsense OpenERP Installation Guide

This is a no-nonsense guide to the installation of OpenERP — the popular open source and customizable ERP solution — aimed at the complete newbie. Of course, there has to just a little bit of “nonsense” to get you started. So, here it is: (a) You need to have PostgreSQL installed as the database backend for OpenERP. (b) OpenERP is written in python so you’ll need some packages for that part. (c) There is a server and a client. The server is important — client can be both a desktop client or a web client. (d) We’ll cover all of this except the web client. You don’t need that to get started. (e) We’re using OpenERP on Ubuntu 11.10 but an older version should also work.

Read more…

Agent Mobility with JADE and JIPMS

A friend and I have been working on Java Agent DEvelopment Framework (JADE) for a while now. The idea is to enhance security mechanisms in the open source agent-deployment platform. The first step we decided to address was the actual mobility of an agent from one platform (in the sense of a dedicated machine running the JADE middleware) to another one. Turned out that it was much harder than one would imagine — especially given the fact that these agents are supposed to be mobile. Anyway, after around two months of part-time efforts, we got the agent working. Since the whole ordeal involved a lot of missing documentation and bad support, I decided to document the process through this tutorial. So, here it is. Read on to see how you can create an agent on one platform, migrate it to another platform, have it do some computation there and come back to the source.  Read more…

Creating UML Sequence Diagrams with TikZ in LaTeX

I’ve been working on my LaTeX skills for some time. The goal is to move towards an all-latex solution for writing research papers, slide sets and other documents. I’m almost there. An important goal was to be able to create all sorts of figures within LaTeX. (Well, originally, the goal was to use open source softwares to create them but it turns out that LaTeX is really good at this stuff.) The package that I’m using for graphics creation is TikZ. Here we’ll cover how we can create sequence diagrams using TikZ and a plugin package.

Here’s what we’re planning on creating.

Sequence Diagram using TikZ (click to enlarge)

First, you need to get the pgf-umlsd.sty file from over here and put it in a folder. Then, create your minimal working example (main document) using the following code.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,shadows}
\usepackage{pgf-umlsd}

\begin{document}

\begin{sequencediagram}
\newthread[white]{u}{User}
\newinst[3]{b}{Browser}
\newinst[3]{t}{TPM}
\newinst[3]{p}{TTP}

\begin{call}{u}{Init()}{b}{}
\end{call}

\begin{call}{u}{AIKAuthSecret}{b}{}

  \mess{b}{verifyAIKAuthSecret}{t}

  \begin{call}{b}{get AIK$_{pub}$}{t}{AIK$_{pub}$}
  \end{call}

\end{call}
  \begin{sdblock}{Loop}{}

    \begin{call}{u}{Do Something}{p}{AIK$_{pub}$}
    \end{call}
  \end{sdblock}
\end{sequencediagram}

\end{document}

As you can see, the pgf-umlsd package is really awesome. You first create a new thread using the syntax \newthread[color]{variable}{ClassName}. Then, you create instances using \newinst[distance]{variable}{InstanceName}. Afterwards, use call environment to specify calls. All you need to do is specify the caller, the message label, recipient and return label. Messages are similar and can be done through the \mess command. You can insert blocks using the sdblock environment. All it needs is a label and a description. A block will automatically surround everything within this environment. Oh, and calls can be nested.

If you’re like me and don’t like your object names underlined, you can pass the [underline=false] option to the pgf-umlsd package.

p.s. Your output may be a little bit different from mine because I modified the package file to suit my personal liking — just a bit though.

How to Create a Beamer Template — A Newbie’s Tutorial

I started switching full-time to Ubuntu (once again) a couple of weeks ago. Turns out, it’s in much better condition than when I last tried it. Anyway, one of the problems was finding a replacement for Powerpoint. I hate creating presentations for classes — in fact, I think they’re counter-productive — but I have no choice for the moment. So, I decided to give LibreOffice Impress a chance. That was an hour of my life down the drain. Finally, I returned to beamer. Of course, I had to write my own theme because I couldn’t use the same theme used by all the rest of the world. To cut this long and boring story short, I tried very hard to find a tutorial on writing beamer themes, couldn’t do so, learned it through experiment and decided to write the tutorial myself. Here is that tutorial. Read more…

LaTeX Screencasts

I’ve started putting together a couple of screencasts for those who want to start working with LaTeX. These are aimed at the extreme newbie who wants to learn the basics and get up to speed with the typesetting tool. I’ll be updating this post as I put more videos online inshallah. For now, see the videos below or on Youtube. For best results, view in HD at full screen.

Part I: Introduction

Part II: Creating your first document
Download the files mentioned in the video from here: latex-seminar-files-demo-1.zip

Part III: Bibliographies, Class Files for Conference Styles
Download the files mentioned in the video from here: latex-seminar-files-demo-2.zip

Setting up Exim to Use Amazon Simple Email Service (SES)

Amazon Simple Email Service (SES) is a Email Marketer’s dream come true. It allows you to send bulk emails to customers without fear of having your email land in their spam/junk folder — unless of course you’re sending spam and a huge majority of your “customers” start marking it as such.

More to the point, it’s very easy to setup SES with sendmail and postfix. However, if you’re like most small/medium businesses, you’re using cPanel to host your site and that comes with Exim as the mail server. Of course, Amazon forgot to add instructions for Exim and so, here you are. Let’s begin. Read more…

Varnish Cache for WordPress on cPanel

Varnish is an extremely easy to configure server cache software that can help you counter the ‘slashdot effect’ — high traffic over a small period of time. The way Varnish does this is by sitting between the client and the webserver and providing cached results to the client so that the server doesn’t have to process every page. It’s better than memcache etc because the request never gets to the webserver. You can avoid one of the bottlenecks this way. In this tutorial, we’ll cover how to setup Varnish on a VPS (or dedicated server) where you have root access and are running your site using cPanel/WHM. It also applies to situations where you don’t have cPanel/WHM. You can just skip the cPanel portion if that’s the case. So, let’s get started.

Read more…

Arabic/Urdu Typesetting the Easy Way

As the regular readers might know, I’m a big fan and regular user of the LaTeX typsetting system. Keeping to the tradition of occasionally posting a LaTeX tutorial on the blog, here’s one that will be useful to all those that are trying to get up and running with XeTeX — the unicode support adding big brother to the TeX typesetting system. XeTeX basically allows you to use all the Opentype (and other) fonts installed on your system — and it adds unicode support. That means you can use the latest Adobe fonts you’ve got as well as all the Arabic, Urdu, Chinese and Japanese fonts and typeset them as beautifully as you would any Latin script in LaTeX. It’s a hassle to set it up though and you wouldn’t find many tutorials or how-tos on the Internet.

So, here’s one that will allow you to setup and start using XeTeX — especially if you’re trying to find a way to easily typeset Arabic/Urdu. Let’s get started: First, download and install MikTeX 2.7+ (for Windows or any other LaTeX package for your favourite OS). I use 2.8 but I guess you should download the latex (2.9). Everything after 2.6 t has XeTeX built-in. You should download the basic installer from here.

Install also the TeXMaker IDE. We’re going to configure that in a little while to use XeTeX instead of LaTeX. Get the Scheherazade font from the SIL page. You can just extract the zip file anywhere and copy the .ttf file into C:\Windows\Fonts folder. That installs the font required for Arabic typesetting.

Now, fire up TexMaker, go to Options menu and click on ‘Configure Texmaker’. In the Pdflatex section, replace pdflatex with xelatex.

Configure texmaker for XeLaTeX

Create a new file and insert the following code:

\documentclass{article}
\usepackage{arabxetex}
\begin{document}

\begin{arab}[novoc]
mi_tAl: \aemph{45} darajaT
\end{arab}

\end{document}

Before we build, you might need to refresh the font-cache for XeLaTeX (especially if you’ve used it before). For that, go to your MikTeX bin directory and enter the command fc-cache.exe --force. It might take a while but it should run without any errors.

Now, back to Texmaker   and ‘Quick Build’.

Build ArabXeTeX

You should be able to see the output like so:

Arabic Output

During the quick build, you might get a dialog box saying that a certain package is missing and you need to install it. If so, just click ‘Ok’ or ‘Install’ and it will be automatically installed on-the-fly by MikTeX. (You’ll need an internet connection though.) If it simply exits giving some error about a missing .sty file (look at the bottom of the screen for the errors/output messages) — you need to open up the “Package Manager” from the MikTeX folder in the start menu and install that package. For example, if you get the error, “Missing arabxetex.sty”, search for arabxetex package, select it in the list and click on the ‘install button’. Then try to quick build again. Let me know in the comments below if you have any errors and I’ll try to help you out.

Installing MikTeX Packages

Finally, you can look at the original documentation for ArabXeTeX for the details of use. I’ll leave you with another output from the examples in that doc.

Another example output from ArabXeTeX