Converting a Django App to a REST API

This ar­ti­cle demon­strates how easy it is to con­vert a Django app into a REST API us­ing the REST frame­work. The un­der­ly­ing as­sump­tion here is that the reader’s ma­chine has a work­ing ver­sion of Python and Python-pip.

OpenSource For You - - Developers - By: Ashish Singh Bhatia The au­thor is a tech­nol­ogy en­thu­si­ast and a FOSS fan. He loves to ex­plore new tech­nol­ogy, and to work on Python, Java and An­droid. He can be reached at ast.bhatia@gmail.com. He blogs at https://open­freei­dea.wordpress.com/ and http:

Django is a well-known Web frame­work, which al­lows de­vel­op­ers to de­velop ORMbased apps at a fast pace. If you don’t have Django in­stalled on your sys­tem, use pip in­stall Django on a ter­mi­nal. It will in­stall Django on your sys­tem.

Once Django is in­stalled, let’s cre­ate a project, within which we will cre­ate a con­tacts app. Open a ter­mi­nal or com­mand prompt and ex­e­cute the fol­low­ing com­mand [re­fer to Fig­ure 2]: cd mypro­ject django-ad­min star­tapp con­tacts

Open the mypro­ject di­rec­tory and you can see the struc­ture shown in Fig­ure 3.

Open mod­els.py in the con­tacts di­rec­tory and cre­ate a class Con­tact to rep­re­sent the con­tact:

from django.db im­port mod­els # Cre­ate your mod­els here. class Con­tact( mod­els. Model ):

first name= mod­els. Char Field( max_ length=100)

last name= mod­els. Char Field( max_ length=100, null=True, blank=True)

ad­dress= mod­els. Text Field( max_ length=100)

city= mod­els. Char Field( max_ length=100)

state= mod­els. Char Field( max_ length=100)

coun­try= mod­els. Char Field( max_ length=100)

home­_­phone = mod­els. In­te­ger Field( null= True, blank= True)

work_­phone = mod­els. In­te­ger Field( null= True, blank= True)

home­_other = mod­els. In­te­ger Field( null= True, blank= True)

work_other = mod­els. In­te­ger Field( null= True, blank= True) mo­bile_ prim= mod­els. In­te­ger Field () mo­bile_seco = mod­els.

In­te­ger Field( null= True, blank= True)

Open set­tings.py in the mypro­ject di­rec­tory and add con­tacts in the in­stalled app (re­fer to Fig­ure 4).

In set­tings.py, at the end you can see data­bases that show where the data­base and ta­ble will be cre­ated. For this ex­am­ple, we will use SQLite3 as the data­base. To cre­ate a con­tacts ta­ble, ex­e­cute the fol­low­ing com­mand:

python man­age.py makem­i­gra­tions

This will cre­ate the mi­gra­tions script. You can see that the mi­gra­tions di­rec­tory is cre­ated in the con­tacts di­rec­tory with 0001_ini­tial.py. Now, us­ing the mi­grate com­mand, cre­ate the ta­ble. It will cre­ate some other ta­bles also.

python man­age.py mi­grate

You can see the db.sqlite3 file in the mypro­ject di­rec­tory. Our app is ready, but still has no view that will gen­er­ate any out­put. We can use Django tem­plates to cre­ate a view, but can omit that sec­tion as we want a REST based in­ter­face for con­tacts. The next sec­tion will ex­plore how to con­vert this app to a REST API.

Why REST?

By us­ing REST we en­sure that our ap­pli­ca­tion can be ac­cessed from any­where and have any front-end. Let’s sup­pose we want to cre­ate a web­site us­ing the latest tech­nol­ogy like Re­act or An­gu­lar, and also a mo­bile app or hy­brid mo­bile app. How­ever, if the web­site al­ready ex­ists and we want to cre­ate only a mo­bile app or Re­act based app, we need to mod­ify and re­turn JSON in­stead of HTML. In­stead of cre­at­ing two dif­fer­ent types of back­end logic to re­turn HTML, JSON or some other for­mat, we can ex­pose our ap­pli­ca­tion as a REST API, which is for any client to con­sume and dis­play it in the way it is ca­pa­ble of. Any client re­quest­ing the re­source will get JSON as out­put, and will de­cide how to parse and dis­play data.

For converting the ap­pli­ca­tion to a REST API, we need to use the rest_frame­work and per­form the fol­low­ing steps.

Open a ter­mi­nal or com­mand prompt and ex­e­cute the fol­low­ing com­mand:

pi pins talld­jang or est frame­work

Open set­tings.py in the mypro­ject di­rec­tory, and add rest_frame­work in INSTALLED_APPS.

Cre­ate new files named se­ri­al­iz­ers. py, views.py and urls.py in the con­tacts di­rec­tory.

For any model to be ex­posed as REST we need to cre­ate a se­ri­al­izer class in se­ri­al­izer.py. We will cre­ate the Con­tactS er ia liz er class with all the fields. Open se­ri­al­izer.py and add the fol­low­ing code to it:

from rest_frame­work im­port se­ri­al­iz­ers from mod­els im­port Con­tact

class Con­tactS er ia liz er( se­ri­al­ize rs. ModelSe­ri­al­izer): class Meta: model = Con­tact fields = ‘__al­l__’

We need to spec­ify URLs and views for the file. First, let’s cre­ate a view with the get and post meth­ods. The get method will re­turn all data in JSON for­mat, and the post method will save the data after val­i­dat­ing it. This can be ex­tended to use the delete and put logic also. Open the views.py file in the con­tacts di­rec­tory and add the fol­low­ing code:

from rest_frame­work im­port sta­tus from rest_ frame­work. dec­o­ra­tors im­port api_view from rest_ frame­work. re­sponse im­port Re­sponse from mod­els im­port Con­tact from se­ri­al­iz­ers im­port Con­tactS er ia liz er

@api_view([‘GET’, ‘POST’]) def con­tact_ list( re­quest ):

“””

// List all snip­pets, or cre­ate a new snip­pet.

“”” if re­quest.method == ‘GET’:

con­tacts = Con­tact.ob­jects. all()

se­ri­al­izer = Con­tactS er ia liz er( con­tacts, many= True)

re­turn Re­sponse( s er ia liz er. data)

elif re­quest.method == ‘POST’:

se­ri­al­izer = Con­tactS er ia liz er( data= re­quest. data) ifs er ia liz er. is_ valid (): se­ri­al­izer.save() re­turn Re­sponse( s er ia liz er. data, sta­tus= sta­tus. HTTP _201_ CRE­ATED)

re­turn Re­sponse( s er ia liz er. er­rors, sta­tus= sta­tus. HTTP _400_ BAD_ RE­QUEST)

We need to spec­ify URLs to reach this view. Open urls.py in the mypro­ject di­rec­tory, where we will in­clude the con­tacts view for pro­cess­ing.

from django.conf.urls im­port in­clude, url from django.con­trib im­port ad­min

url­pat­terns = [ # Ex­am­ples:

# url(r’^$’, ‘mypro­ject.views. home’, name=’home’),

# url(r’^blog/’, in­clude(‘blog. urls’)),

url(r’^ad­min/’, in­clude( ad min. site. urls)),

url(r’^con­tacts/’, in­clude (‘ con­tacts. ur ls ’)),

]

Open urls.py in the con­tacts di­rec­tory, which will point to the view we cre­ated in views.py in this di­rec­tory.

from django.conf.urls im­port in­clude, url from django.con­trib im­port ad­min from con­tacts im­port views

url­pat­terns = [

# Ex­am­ples:

# url(r’^$’, ‘mypro­ject.views. home’, name=’home’),

# url(r’^blog/’, in­clude(‘blog. urls’)), ]

url(r’^api/’, views. con­tact_ list ),

Now that we have done that, con­tacts/api will call our view con­tact_ list and dis­play all data from con­tacts. To test this, open a ter­mi­nal and start the server us­ing the fol­low­ing com­mand:

python man­age.py run­server

Open a browser with the URL lo­cal­host:8000/con­tacts/api and it will dis­play what is shown in Fig­ure 7.

As we have no records, the get sec­tion dis­plays no data. In the post sec­tion, add data in JSON for­mat as shown in Fig­ure 8, and press the Post but­ton.

Our views post por­tion will be ex­e­cuted and data will be in­serted in SQLite3. The page will get reloaded to dis­play the record (Fig­ure 9).

If we are cre­at­ing a REST API, then get, post, put and delete are com­monly used. Cre­at­ing the views with a func­tion for all mod­els with all meth­ods can be a te­dious job. In­stead of the func­tion base view, we can cre­ate a class base view by in­her­it­ing the gener­ics view to pro­vide com­mon func­tion­al­ity. Change views.py as fol­lows:

from rest_frame­work im­port sta­tus from rest_ frame­work. dec­o­ra­tors im­port api_view from rest_ frame­work. re­sponse im­port Re­sponse from mod­els im­port Con­tact from se­ri­al­iz­ers im­port Con­tactS er ia liz er from rest_frame­work im­port gener­ics

class Con­tact List( gener­ics. List Cre­ate AP I View ): query set= Con­tact. ob­jects. all () se­ri­al­iz­er_­class = Con­tactS er ia liz er

class Con­tact De­tail( gener­ics. Re­trieve Up­date De­stroy AP I View ): query set= Con­tact. ob­jects. all () se­ri­al­iz­er_­class = Con­tactS er ia liz er

Change urls.py in the con­tacts di­rec­tory to point to the class base view as shown be­low:

from django.conf.urls im­port in­clude, url from django.con­trib im­port ad­min from con­tacts im­port views

url­pat­terns = [

# Ex­am­ples:

# url(r’^$’, ‘mypro­ject.views.home’, name=’home’),

# url(r’^blog/’, in­clude(‘blog. urls’)),

url(r’^api/’, views.Con­tac­tList. as_view()),

]

Re­fresh the page and you will see that the post sec­tion has a form like struc­ture. You can use the raw for­mat also, but a new form like struc­ture is more el­e­gant.

A lot more can be done in REST; this ar­ti­cle is just to get things rolling.

django-ad­min start­pro­ject mypro­ject Fig­ure 1: In­stalling Django us­ing Pip

Fig­ure 2: Cre­at­ing a project and app

Fig­ure 3: Project and app di­rec­tory struc­ture

Fig­ure 4: set­tings.py in the mypro­ject di­rec­tory

Fig­ure 5: Out­put of makem­i­gra­tions com­mand

Fig­ure 6: Run­ning the mi­grate com­mand

Fig­ure 7: Out­put of the first rest API

Fig­ure 8: Post­ing data

Fig­ure 9: After post­ing data

Fig­ure 10: HTML form for post

Newspapers in English

Newspapers from India

© PressReader. All rights reserved.