Categories
code Django git python

Django management commands from admin interface

This need came up when during app deployment, needed to run some management commands without ssh-ing into the server or using the terminal.
Thankfully Django management command can be called anywhere using management.call_command()

This is a brief one, view code on GitHub here:
https://github.com/NEbere/data-import/tree/master

You need to install the admin_plus package with pip, ensure your virtual environment is setup and activated if that’s what you’re using, in any case, ensure you have the right environment setup and running for your app before installing to avoid any issues ๐Ÿ˜‰

Install admin_plus:

pip install django-adminplus

Add adminplus to INSTALLED_APPS in your settings file

If youโ€™re using Django 1.7, you should also replace django.contrib.admin with django.contrib.admin.apps.SimpleAdminConfig in your installed apps, in order to disable the automatic auto-discovery:

so update ‘django.contrib.admin’ to ‘django.contrib.admin.apps.SimpleAdminConfig’ in INSTALLED_APPS in your settings file

import AdminSitePlus in urls.py of your main package, the file where URL’s from installed apps are registered
hint: this is where you have the admin URL defined

In that same file, add this for the admin_plus

admin.site = AdminSitePlus()
admin.autodiscover()

Now, head to the admin.py file in your app and call the command you want to execute.

from django.contrib import admin
from .models import Movie
from django.core import management
from django.shortcuts import redirect

class MovieAdmin(admin.ModelAdmin):
    @admin.site.register_view('import_movies_from_url', 'Import Movies from URL')
    def import_movies_from_url(request):
        print('import movies here')
        try:
            management.call_command('import_from_url')
            message = 'successfully imported data from URL'

        except Exception as ex:
            message = 'Error importing from data from URL {}'.format(str(ex))

        admin.ModelAdmin.message_user(Movie, request, message)
        return redirect('admin:index')

admin.site.register(Movie, MovieAdmin)


the command I am calling here is import_from_url and that name corresponds to the file where I defined the command (minus the file .py file extension)

This does two things:
1. Makes your Model available on the admin interface, you can create, update, delete models objects from the admin interface once your models are registered.
2. Provides a link that when clicked runs the management command defined to be run.

Screen Shot 2017-10-26 at 1.36.02 PM

More details on admin_plus

Again, here is the github repo with all the import scripts and sample files:
https://github.com/NEbere/data-import/blob/call-management-command-from-admin/
Happy coding ๐Ÿ™‚

Categories
code git

Import data into database – django app

Steps to import data into your Djangoย app

So you have a Django app and want to load data from a URL, a CSV file or a JSON file, I got you ๐Ÿ™‚
First, create your models, make migrations, migrate and all that setup you have to do, but I’m sure you got all that covered ๐Ÿ˜‰

See it on Github here: https://github.com/NEbere/data-import/tree/master

Import from URL:

This code gets data from a URL, be sure to have requests installed or any other HTTP library of choice.

"""
Import json data from URL to Datababse
"""
import requests
import json
from import_data.models import Movie #Import your model here
from django.core.management.base import BaseCommand
from datetime import datetime

IMPORT_URL = 'https://jsonplaceholder.typicode.com/photos' # URL to import from

class Command(BaseCommand):
  def import_movie(self, data):
  title = data.get('title', None)
  url = data.get('url', None);
  release_year = datetime.now()
  try: #try and catch for saving the objects
    movie, created = Movie.objects.get_or_create(
    title=title,
    url=url,
    release_year=release_year
    )
    if created:
      movie.save()
     display_format = "\nMovie, {}, has been saved.
     print(display_format.format(movie))
  exceptExceptionas ex:
    print(str(ex))
    msg = "\n\nSomething went wrong saving this movie: {}\n{}".format(title, str(ex))
    print(msg)
  def handle(self, *args, **options):
  """
  Makes a GET request to the API.
  """
  headers = {'Content-Type': 'application/json'}
  response = requests.get(
  url=IMPORT_URL,
  headers=headers,
  )
  response.raise_for_status()
  data = response.json()
  for data_object in data:
  self.import_movie(data_object)

Import from files (JSON):

To import from a file, read the file location

import os # Add os import to the imports used above for URL
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #Define BASE_DIR or import of it is previously defined
class Command(BaseCommand):
  def import_movie_from_file(self): 
   data_folder = os.path.join(BASE_DIR, 'import_data', 'resources/json_file')
   for data_file in os.listdir(data_folder):
     withopen(os.path.join(data_folder, data_file), encoding='utf-8') as data_file:
       data = json.loads(data_file.read())
       for data_object in data:
         title = data_object.get('title', None)
         url = data_object.get('url', None)
         release_year = datetime.now()
         # Use the try and catch used above here as it's the same model
 def handle(self, *args, **options):
 """
 Call the function to import data
 """
 self.import_movie_from_file() # call the import function in handle

Import from files (CSV):

To import from a csv uses the same steps defined for JSON file import above with the difference been importing csv, and how the data is parsed.

import csv # Add csv import to the imports used above for JSON import
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #Define BASE_DIR or import of it is previously defined
class Command(BaseCommand):
  def import_movie_from_csv_file(self): 
   data_folder = os.path.join(BASE_DIR, 'import_data', 'resources/csv_file') # folder where csv file is stored
   for data_file in os.listdir(data_folder):
     withopen(os.path.join(data_folder, data_file), encoding='utf-8') as data_file:
       data = json.loads(data_file.read())
       for data_object in data:
         title = data_object[1] # the value at index 0 is the ID and we dont need that here
         url = data_object[2]
         release_year = datetime.now()
         # Use the try and catch used above here as it's the same model
 def handle(self, *args, **options):
 """
 Call the function to import data
 """
 self.import_movie_from_csv_file() # call the import function in handle

Run the import commands

 python manage.py import_from_url # import_from_url is the name of the file where the command is defined without the extension, that is, .py

for more about requests http://docs.python-requests.org/en/master/

Again, here is the github repo with all the import scripts and sample files:
https://github.com/NEbere/data-import/tree/master
Happy coding ๐Ÿ™‚