· Hakan Çelik · Django / Database · 4 dk okuma

Using Multiple Databases in a Django Project

We'll learn how to use multiple databases with Django, how to create applications with Django, how to find the IP addresses of visitors, and how to use 'from django.db.models import F'.

Using Multiple Databases in a Django Project

What will we learn?

  • How to use multiple databases with Django
  • How to create an application with Django
  • How to find the IP addresses of visitors
  • How to use from django.db.models import F

Requirements

  • python3
  • django 1.11
  • Virtualenv

If you need information about Virtualenv, check out this address: Virtualenv

Install Virtualenv and the required packages (requirements) from the address above.

[===========]

If you’re wondering why you would ever need multiple databases, here’s an example: on coogger.com I store the number of times content has been read along with the visitor’s IP address and the relevant content’s id number. If the person has already read it (i.e., if their IP address and the current content’s id are already recorded), I don’t increment the view count. Now, other data is also being recorded in the same database, and IP addresses aren’t that valuable compared to other data — like user information or shared content — while being written very frequently. So to separate this useful and not-so-useful data, I set up multiple databases. Let’s do this together.

First, what do we need?

You should already have a Django project with an application named myapp inside it. Let’s say the database settings section in your settings.py file looks like this:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'sqlite3'),
    },
}

That’s correct. Now navigate to your application directory named myapp and open a console to create a new application:

python3 manage.py startapp multiapp

A new application has been created. Go back to settings.py and make the following changes:

INSTALLED_APPS = [
    "multiapp",
    "myapp",
.....
]
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'sqlite3'),
    },
    'multi': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'multidb'),
    },
}
DATABASE_APPS_MAPPING = {'multiapp': 'multi'}

We added our new application to INSTALLED_APPS and configured a second database. DATABASE_APPS_MAPPING will help us choose which application uses which database.

Go to multiapp/models.py and write a model to store the IP addresses we’ll collect from visitors, like this:

from django.db import models
from myapp.models import Blog

class Blogviews(models.Model):
    content = models.ForeignKey(Blog, on_delete=models.CASCADE)
    ip = models.GenericIPAddressField() # our field for IP addresses

    class Meta:
        app_label = 'multiapp'

You have a Blog model in your myapp application — we linked it to the Blog model with a ForeignKey. app_label = ‘multiapp’ — this part tells Django which database to use based on the name defined in DATABASE_APPS_MAPPING. We’re saying: this model belongs to the multiapp application and will use the multidb database.

Now let’s get the IP address — go to myapp/views.py and write the following:

from django.db.models import F
from multiapp.models import Blogviews

def up_blog_view(request, queryset):
    try:
        ip = request.META["HTTP_X_FORWARDED_FOR"].split(',')[-1].strip()
    except:
        ip = None
    if ip is None:
        return False
    if not Blogviews.objects.filter(blog=queryset, ip=ip).exists():
        Blogviews(content=queryset, ip=ip).save()
        queryset.views = F("views") + 1
        queryset.save()

We wrote a function called up_blog_view with two parameters: the incoming request and the incoming queryset (the Blog data). With request.META["HTTP_X_FORWARDED_FOR"].split(',')[-1].strip() we get the IP address from the request. If it’s not None, we check using Blogviews and exists() whether this combination was previously recorded. If it wasn’t, we create a new record and increment the view count by one with F("views") + 1, then save it.

How do we use this function?

Open myapp/views.py and write something like this:

from multiapp.views import up_content_view
from models import Blog

def home(request, id):
    queryset = Blog.objects.filter(id=id)[0]
    up_content_view(request, queryset)

Usage is similar to the above. Note that you’ll also need to add an integer field called views to your Blog model to store the view count.

We’re at the final stages. Everything is set — now we need to synchronize the databases. The commands should be as follows:

python3 manage.py migrate --database multi
python3 manage.py makemigrations multiapp
python3 manage.py migrate
python3 manage.py makemigrations myapp

multiapp/admin.py

from django.contrib.admin import ModelAdmin, site
from multiapp.models import Blogviews

class ViewsAdmin(ModelAdmin):
    list_ = ["content_id", "ip"]
    list_display = list_
    list_display_links = list_
    search_fields = list_

site.register(Blogviews, ViewsAdmin)

Result?

Back to Blog

Related Posts

View All Posts »
Extending the User Model

Extending the User Model

Django · 5 dk

As you know, Django comes with a user model that has certain properties — name, last name, email, password, etc. While these fields save the day in most cases, sometimes they're not enough. Depending on the project you're building, users may need to have more properties. That's what we'll achieve by extending the user model.

How to Create Custom Management Commands

How to Create Custom Management Commands

Django · 4 dk

Everyone uses this part of Django. Even those who have never used Django and are just starting to learn it use this area first — they open a console from the project directory and immediately start a new project to begin coding.

Building Login, Register, and Logout Pages

Building Login, Register, and Logout Pages

Django · 9 dk

In this post, instead of writing CSS for the page design, I'll use a front-end framework called Uikit. The code I use here comes from a project called Eatingword that I'm developing to keep my Django skills fresh and learn new things.