CINXE.COM
David Landup - Stack Abuse
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><title>David Landup - Stack Abuse</title><link rel="canonical" href="https://stackabuse.com/author/david/"/><meta property="og:url" content="https://stackabuse.com/author/david/"/><meta name="twitter:url" content="https://stackabuse.com/author/david/"/><link rel="next" href="https://stackabuse.com/author/david/page/2/"/><meta property="og:site_name" content="Stack Abuse"/><meta property="og:type" content="profile"/><meta property="og:title" content="David Landup - Stack Abuse"/><meta name="twitter:card" content="summary"/><meta name="twitter:title" content="David Landup - Stack Abuse"/><meta name="twitter:site" content="@StackAbuse"/><script type="application/ld+json">{ "@context": "https://schema.org", "@type": "Person", "sameAs": [ "https://www.linkedin.com/in/david-landup-859455144/" ], "name": "David Landup", "url": "https://stackabuse.com/author/david/", "mainEntityOfPage": { "@type": "WebPage", "@id": "https://stackabuse.com/" }, "image": { "@type": "ImageObject", "url": "https://s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg" } }</script><meta name="next-head-count" content="14"/><link href="//fonts.googleapis.com" rel="preconnect"/><link href="//fonts.gstatic.com" rel="preconnect" crossorigin="true"/><link href="//cdnjs.cloudflare.com" rel="preconnect"/><link href="//s3.stackabuse.com" rel="preconnect"/><link href="//googletagmanager.com" rel="dns-prefetch"/><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="HandheldFriendly" content="True"/><link rel="shortcut icon" sizes="any" href="/assets/images/favicon.ico"/><link rel="shortcut icon" type="image/svg+xml" href="/assets/images/favicon.svg"/><link rel="preload" as="style" href="//fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"/><link rel="preload" as="style" href="//fonts.googleapis.com/css?family=Nunito:400,400i,700,700i&display=swap"/><meta name="referrer" content="no-referrer-when-downgrade"/><link rel="alternate" type="application/rss+xml" title="Stack Abuse" href="https://stackabuse.com/rss/"/><link rel="preload" href="/_next/static/css/9184903490bed3cd.css" as="style"/><link rel="stylesheet" href="/_next/static/css/9184903490bed3cd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="/_next/static/chunks/webpack-d4c8322ddb9caf79.js" defer=""></script><script src="/_next/static/chunks/framework-1dabaad0401a053e.js" defer=""></script><script src="/_next/static/chunks/main-7cc54cdcfbd9bea6.js" defer=""></script><script src="/_next/static/chunks/pages/_app-530fa3a28589599c.js" defer=""></script><script src="/_next/static/chunks/c78d26b1-fe043233b220ebfb.js" defer=""></script><script src="/_next/static/chunks/816-dfcc5ef3cff7cadb.js" defer=""></script><script src="/_next/static/chunks/3646-f084444085f451b1.js" defer=""></script><script src="/_next/static/chunks/7329-ea47eb245049fa3f.js" defer=""></script><script src="/_next/static/chunks/2221-aa293f4e0cf5d5c8.js" defer=""></script><script src="/_next/static/chunks/pages/author/%5B...slug%5D-9a0a529e41423fb6.js" defer=""></script><script src="/_next/static/1739247265773/_buildManifest.js" defer=""></script><script src="/_next/static/1739247265773/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div><nav class="bg-white pb-2 border-b shadow"><div class="mx-8 px-2 sm:px-4 lg:px-8"><div class="flex justify-between h-16"><div class="flex items-center px-2 lg:px-0"><a href="/"><div class="flex-shrink-0 flex items-center"><svg class="h-6 w-full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 494.36 63"><defs><style>.cls-1{fill:#363636}.cls-2{fill:#f29c80}.cls-3{fill:#b34a28}.cls-4{fill:#f16335}</style></defs><title>SA Logotype</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M104.94,27.65q-3.15-1.44-4.65-2.16c-1-.48-2.17-1.12-3.49-1.91A10.35,10.35,0,0,1,94,21.35a3.58,3.58,0,0,1-.82-2.27,4.79,4.79,0,0,1,1.74-3.89,7.6,7.6,0,0,1,5-1.44,16,16,0,0,1,5.61,1.15,27.13,27.13,0,0,1,4.1,1.84c.73.46,1.3.83,1.71,1.12l5.2-10.8-2-1.44A28.63,28.63,0,0,0,108,2.84a29.37,29.37,0,0,0-9-1.4A18.5,18.5,0,0,0,86.2,6.52a16.81,16.81,0,0,0-5.61,13.06,14.64,14.64,0,0,0,2.81,8.61,21.59,21.59,0,0,0,7.93,6.66c.82.43,2.09,1.07,3.8,1.91s2.94,1.46,3.69,1.87a27.75,27.75,0,0,1,2.6,1.65,6.9,6.9,0,0,1,2,2.09,4.57,4.57,0,0,1,.58,2.27q0,5.84-8.14,5.83a14.52,14.52,0,0,1-6.46-1.87,35.41,35.41,0,0,1-5.1-3c-.95-.74-1.71-1.35-2.25-1.83L75.67,55.15l.89.79a19.23,19.23,0,0,0,2.8,2c1.28.77,2.71,1.55,4.31,2.34a26.52,26.52,0,0,0,6,2,33.14,33.14,0,0,0,7.25.79,29.54,29.54,0,0,0,8-1,21.94,21.94,0,0,0,6.74-3.21,14.53,14.53,0,0,0,4.79-6,21.36,21.36,0,0,0,1.74-8.93,13.77,13.77,0,0,0-3.86-9.54A28,28,0,0,0,104.94,27.65Z"></path><path class="cls-1" d="M143.66,50.69a5.8,5.8,0,0,1-1.17.57,3.84,3.84,0,0,1-1.43.29q-2.75,0-2.74-5.11V34.7h7.39V25h-7.39V11.23H126.21V25h-5.06V34.7h5.06V48.89a22.21,22.21,0,0,0,.55,5,16,16,0,0,0,1.81,4.47,9,9,0,0,0,3.73,3.38A12.76,12.76,0,0,0,138.18,63a17.23,17.23,0,0,0,8.9-2.3l-3-10.3Z"></path><path class="cls-1" d="M177.44,28.51A15.41,15.41,0,0,0,166,23.9a15.82,15.82,0,0,0-12.51,5.69,20.47,20.47,0,0,0-4.93,13.9,20.33,20.33,0,0,0,4.93,13.86A15.85,15.85,0,0,0,166,63a14.47,14.47,0,0,0,11.49-5.26h.14v4.18h12V25H177.44Zm-2,21.17a7.68,7.68,0,0,1-5.85,2.45,7.79,7.79,0,0,1-6-2.41,8.74,8.74,0,0,1-2.26-6.23,8.69,8.69,0,0,1,2.36-6.27,8.15,8.15,0,0,1,11.63,0,8.69,8.69,0,0,1,2.36,6.27A8.74,8.74,0,0,1,175.43,49.68Z"></path><path class="cls-1" d="M216.43,34.34a9.4,9.4,0,0,1,5.88,1.73l4.11-8.71-1.16-.86a15,15,0,0,0-4.18-1.73,22.57,22.57,0,0,0-6.43-.87,18.72,18.72,0,0,0-13.57,5.8,18.81,18.81,0,0,0-5.85,13.86,18.52,18.52,0,0,0,5.85,13.72A18.83,18.83,0,0,0,214.65,63a22,22,0,0,0,6.54-.94,20,20,0,0,0,3.89-1.47c.57-.36,1-.66,1.34-.9l-4.11-8.86-.61.43a9.12,9.12,0,0,1-2.16.87,10.87,10.87,0,0,1-3.11.43,7.75,7.75,0,0,1-5.88-2.66,9.22,9.22,0,0,1-2.46-6.48A9.1,9.1,0,0,1,210.55,37,7.72,7.72,0,0,1,216.43,34.34Z"></path><polygon class="cls-1" points="271.43 24.98 255.69 24.98 243.45 37.87 243.45 0 231.34 0 231.34 61.92 243.45 61.92 243.45 47.16 257.47 61.92 273.07 61.92 254.74 42.62 271.43 24.98"></polygon><polygon class="cls-1" points="296.96 2.52 274.18 61.92 288 61.92 302.84 20.88 302.98 20.88 317.82 61.92 331.63 61.92 308.86 2.52 296.96 2.52"></polygon><path class="cls-1" d="M357.42,23.9a15.41,15.41,0,0,0-11.49,4.61V0H333.82V61.92h12V57.74h.14A14.47,14.47,0,0,0,357.42,63a15.88,15.88,0,0,0,12.52-5.65,20.38,20.38,0,0,0,4.92-13.86,20.51,20.51,0,0,0-4.92-13.9A15.86,15.86,0,0,0,357.42,23.9Zm2.33,25.82a7.8,7.8,0,0,1-5.95,2.41A7.65,7.65,0,0,1,348,49.68a8.69,8.69,0,0,1-2.29-6.19A8.64,8.64,0,0,1,348,37.22a7.7,7.7,0,0,1,5.78-2.44,7.78,7.78,0,0,1,5.84,2.44A8.64,8.64,0,0,1,362,43.49,8.78,8.78,0,0,1,359.75,49.72Z"></path><path class="cls-1" d="M405.78,42.55c0,3.65-.53,6.24-1.57,7.78s-2.83,2.3-5.34,2.3-4.29-.77-5.33-2.3S392,46.2,392,42.55V25h-12.1V45.65q0,9.21,4.54,13.28T398.87,63q9.92,0,14.47-4.07t4.55-13.28V25H405.78Z"></path><path class="cls-1" d="M449.11,42.19A20.21,20.21,0,0,0,445.79,40a23.31,23.31,0,0,0-3.69-1.44,8.7,8.7,0,0,1-1-.29c-.44-.14-.74-.25-.93-.32l-.82-.32-.78-.33-.65-.32a2.25,2.25,0,0,1-.58-.4c-.12-.12-.24-.26-.38-.43a1.25,1.25,0,0,1-.27-.54,2.25,2.25,0,0,1-.07-.58,1.82,1.82,0,0,1,.85-1.76,6.53,6.53,0,0,1,2.91-.47,16,16,0,0,1,7.8,2.31l4-8.36-1.43-.72a22.21,22.21,0,0,0-4.38-1.44,24.9,24.9,0,0,0-5.95-.72q-7,0-11.18,3.14a10.32,10.32,0,0,0-4.14,8.74,9.07,9.07,0,0,0,1.91,6,18.12,18.12,0,0,0,5.2,4.06,28.82,28.82,0,0,0,3.59,1.59A14.8,14.8,0,0,1,439,49a2.2,2.2,0,0,1,1,1.9c0,1.78-1.26,2.67-3.76,2.67a9.22,9.22,0,0,1-4-1.19A23.33,23.33,0,0,1,429,50.51c-.6-.46-1.08-.85-1.44-1.19L422.61,58l1.5,1.3A17.63,17.63,0,0,0,429,61.78,21,21,0,0,0,436.15,63q16.62,0,16.62-12.6a11.23,11.23,0,0,0-1-4.75A9.24,9.24,0,0,0,449.11,42.19Z"></path><path class="cls-1" d="M494.36,43.49q0-9.43-5.24-14.51T475.55,23.9a18.46,18.46,0,0,0-13.62,5.76,19,19,0,0,0-5.67,13.83,18.9,18.9,0,0,0,5.67,13.79A18.54,18.54,0,0,0,475.55,63q12.72,0,18.19-9.65L485,48.74a13.63,13.63,0,0,1-3.9,3.28,10.84,10.84,0,0,1-4.65.83,8.3,8.3,0,0,1-5.2-1.87q-2.4-1.87-2.4-5.76h25.45A14.91,14.91,0,0,0,494.36,43.49Zm-25.17-5.33a6,6,0,0,1,1.91-4.32,6.77,6.77,0,0,1,4.79-1.66,6.51,6.51,0,0,1,4.48,1.55,7,7,0,0,1,2.15,4.43Z"></path><polygon class="cls-2" points="66.05 19.08 73.15 1.3 57.25 1.3 50.16 19.08 66.05 19.08"></polygon><polygon class="cls-3" points="40.21 43.99 32.99 62.06 48.88 62.06 56.1 43.99 40.21 43.99"></polygon><polygon class="cls-4" points="57.69 40.01 64.46 23.05 48.57 23.05 41.8 40.01 57.69 40.01"></polygon><polygon class="cls-2" points="33.06 19.08 40.16 1.3 24.27 1.3 17.17 19.08 33.06 19.08"></polygon><polygon class="cls-3" points="7.22 43.99 0 62.06 15.89 62.06 23.11 43.99 7.22 43.99"></polygon><polygon class="cls-4" points="24.7 40.01 31.47 23.05 15.58 23.05 8.81 40.01 24.7 40.01"></polygon></g></g></svg></div></a><div class="hidden lg:block lg:ml-6"><div class="hidden lg:ml-6 lg:flex"><a href="/tools/" class="mr-8 inline-flex items-center px-1 pt-1 border-b-2 border-blue-400 text-sm font-medium leading-10 text-gray-500 hover:text-gray-700 focus:outline-none focus:text-gray-700 transition duration-150 ease-in-out">Tools</a><div class="px-1 pt-1 border-b-2 border-green-400 focus:border-gray-300 transition duration-150 ease-in-out"><div class="relative" data-headlessui-state=""><button class="text-gray-500 group rounded-md inline-flex items-center focus:outline-none text-sm font-medium leading-10 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700" type="button" aria-expanded="false" data-headlessui-state=""><span>Learn</span><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="text-gray-400 ml-2 h-5 w-5 group-hover:text-gray-500"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></button></div><div hidden="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"></div></div><a href="/about/" class="ml-8 inline-flex items-center px-1 pt-1 border-b-2 border-red-400 text-sm font-medium leading-10 text-gray-500 hover:text-gray-700 focus:outline-none focus:text-gray-700 transition duration-150 ease-in-out">About</a></div></div></div><div class="hidden mt-4 md:flex md:flex-1 md:items-center md:justify-center md:px-2 lg:ml-6 lg:justify-end"><div class="relative w-1/2 text-gray-400 transition duration-200 focus-within:text-gray-600"><div class="absolute inset-y-0 left-0 flex items-center pointer-events-none" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="h-5 w-5 ml-2"><path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"></path></svg></div><input id="search-field" class="block w-full h-full pl-10 pr-3 py-3 text-sm border-gray-300 text-gray-900 placeholder-gray-500 rounded transition duration-200 focus:outline-none focus:ring-0 focus:border-gray-400" placeholder="Search" type="text"/></div><div class="hidden ml-6 md:flex items-center"><button class="whitespace-nowrap text-base font-medium text-gray-500 hover:text-gray-900">Sign in</button><button class="ml-6 whitespace-nowrap inline-flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-orange-500 hover:bg-orange-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500">Sign up</button></div></div><div class="flex items-center lg:hidden"><button class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out" aria-label="Main menu" aria-expanded="false"><svg class="block h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg><svg class="hidden h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg></button></div></div></div><div class="hidden lg:hidden"><div class="pt-2 pb-3"><a href="/tag/python" class="mt-1 block pl-3 pr-4 py-2 border-l-4 border-transparent text-base font-medium text-gray-600 hover:text-gray-800 hover:bg-gray-50 hover:border-gray-300 focus:outline-none focus:text-gray-800 focus:bg-gray-50 focus:border-gray-300 transition duration-150 ease-in-out">Python</a><a href="/tag/javascript" class="mt-1 block pl-3 pr-4 py-2 border-l-4 border-transparent text-base font-medium text-gray-600 hover:text-gray-800 hover:bg-gray-50 hover:border-gray-300 focus:outline-none focus:text-gray-800 focus:bg-gray-50 focus:border-gray-300 transition duration-150 ease-in-out">JavaScript</a><a href="/tag/java" class="mt-1 block pl-3 pr-4 py-2 border-l-4 border-transparent text-base font-medium text-gray-600 hover:text-gray-800 hover:bg-gray-50 hover:border-gray-300 focus:outline-none focus:text-gray-800 focus:bg-gray-50 focus:border-gray-300 transition duration-150 ease-in-out">Java</a></div></div></nav><main><div class="flex items-stretch min-h-screen"><div class="mx-auto max-w-none lg:max-w-screen-xl px-4 sm:px-6 pb-6"><div class="grid grid-cols-12 sm:gap-x-2 lg:gap-x-3 pt-6"><div class="col-span-12 lg:col-span-3"><img class="object-cover shadow-lg rounded-lg h-60 w-60" src="//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg" alt="David Landup"/><div class="inline-flex py-4"><a href="https://www.linkedin.com/in/david-landup-859455144/"><svg class="h-6 w-6 ml-2 text-gray-500 hover:text-gray-900" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM4.332 8.027a6.012 6.012 0 011.912-2.706C6.512 5.73 6.974 6 7.5 6A1.5 1.5 0 019 7.5V8a2 2 0 004 0 2 2 0 011.523-1.943A5.977 5.977 0 0116 10c0 .34-.028.675-.083 1H15a2 2 0 00-2 2v2.197A5.973 5.973 0 0110 16v-2a2 2 0 00-2-2 2 2 0 01-2-2 2 2 0 00-1.668-1.973z" clip-rule="evenodd"></path></svg></a></div></div><div class="col-span-12 lg:col-span-7"><h1 class="my-1 text-3xl tracking-tight leading-10 font-extrabold text-gray-900 sm:leading-none sm:text-6xl lg:text-4xl xl:text-5xl">David Landup</h1><div class="">Articles: <!-- -->631</div><div class="">Joined: <!-- -->Aug 17, 2018</div><div class="my-4"><p>Entrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.</p> <p>Great passion for accessible education and promotion of reason, science, humanism, and progress.</p> </div></div><div class="lg:col-span-1"></div></div><div class="mt-8 border-t border-gray-200"><h2 class="my-6 text-xl tracking-tight leading-10 font-extrabold text-gray-700 sm:leading-none sm:text-4xl lg:text-2xl xl:text-3xl">Recently published</h2><div class="grid gap-5 lg:grid-cols-3"><div><div class="flex flex-col rounded-lg shadow-lg overflow-hidden"><div class="flex-shrink-0"><a href="/introduction-to-django/"><img class="h-48 w-full object-cover" src="/assets/images/logo-python.png" alt=""/></a></div><div class="flex-1 bg-white p-6 flex flex-col justify-between"><div class="flex-1"><p class="text-sm leading-5 font-medium text-primary">Article</p><a class="block hover:no-underline" href="/introduction-to-django/"><h3 class="mt-2 text-xl leading-7 font-semibold text-gray-900 hover:underline">Introduction to Django</h3><p class="mt-3 text-base leading-6 text-gray-500 break-words">Django is one of today's most widely-used Python web frameworks. For now, we will not focus on the technical definition of a web framework - the guide includes a section dedicated to explaining what frameworks are and what they do - but rather consider the literal meaning of the word,...</p></a></div><div class="mt-6 flex items-center"><div class="flex-shrink-0"><a href="/author/cansin/"><img class="h-10 w-10 rounded-full" src="/assets/images/logo-sa-small.png" alt="Cansın Güler"/></a></div><div class="ml-3"><p class="text-sm leading-5 font-medium text-gray-900"><a href="/author/cansin/" class="hover:underline">Cansın Güler</a></p><div class="flex text-sm leading-5 text-gray-500"><time dateTime="2023-05-05">May 05, 2023</time><span class="mx-1">·</span><span>62<!-- --> min read</span></div></div></div></div></div></div><div><div class="flex flex-col rounded-lg shadow-lg overflow-hidden"><div class="flex-shrink-0"><a href="/loading-a-pretrained-tensorflow-model-into-tensorflow-serving/"><div class="lazyload-wrapper "><div style="height:12rem" class="lazyload-placeholder"></div></div></a></div><div class="flex-1 bg-white p-6 flex flex-col justify-between"><div class="flex-1"><p class="text-sm leading-5 font-medium text-primary">Article</p><a class="block hover:no-underline" href="/loading-a-pretrained-tensorflow-model-into-tensorflow-serving/"><h3 class="mt-2 text-xl leading-7 font-semibold text-gray-900 hover:underline">Loading a Pretrained TensorFlow Model into TensorFlow Serving</h3><p class="mt-3 text-base leading-6 text-gray-500 break-words">You are part of a project that will use deep learning to try to identify what is in images - such as cars, ducks, mountains, sky, trees, etc. In this project, two things are important - the first one, is that the deep learning model trains quickly, with efficiency (because...</p></a></div><div class="mt-6 flex items-center"><div class="flex-shrink-0"><a href="/author/cassia/"><div class="lazyload-wrapper "><div style="height:2.5rem" class="lazyload-placeholder"></div></div></a></div><div class="ml-3"><p class="text-sm leading-5 font-medium text-gray-900"><a href="/author/cassia/" class="hover:underline">Cássia Sampaio</a></p><div class="flex text-sm leading-5 text-gray-500"><time dateTime="2023-03-03">Mar 03, 2023</time><span class="mx-1">·</span><span>28<!-- --> min read</span></div></div></div></div></div></div><div><div class="flex flex-col rounded-lg shadow-lg overflow-hidden"><div class="flex-shrink-0"><a href="/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision/"><div class="lazyload-wrapper "><div style="height:12rem" class="lazyload-placeholder"></div></div></a></div><div class="flex-1 bg-white p-6 flex flex-col justify-between"><div class="flex-1"><p class="text-sm leading-5 font-medium text-primary">Article</p><a class="block hover:no-underline" href="/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision/"><h3 class="mt-2 text-xl leading-7 font-semibold text-gray-900 hover:underline">Training Neural Radiance Field (NeRF) Models with Keras/TensorFlow and DeepVision</h3><p class="mt-3 text-base leading-6 text-gray-500 break-words">Neural Radiance Fields, colloquially known as NeRFs have struck the world by storm in 2020, released alongside the paper &quot;NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis&quot;, and are still the cornerstone of high quality synthesis of novel views, given sparse images and camera positions. Since...</p></a></div><div class="mt-6 flex items-center"><div class="flex-shrink-0"><a href="/author/david/"><div class="lazyload-wrapper "><div style="height:2.5rem" class="lazyload-placeholder"></div></div></a></div><div class="ml-3"><p class="text-sm leading-5 font-medium text-gray-900"><a href="/author/david/" class="hover:underline">David Landup</a></p><div class="flex text-sm leading-5 text-gray-500"><time dateTime="2023-03-02">Mar 02, 2023</time><span class="mx-1">·</span><span>17<!-- --> min read</span></div></div></div></div></div></div><div><div class="flex flex-col rounded-lg shadow-lg overflow-hidden"><div class="flex-shrink-0"><a href="/reading-and-writing-csv-in-bash/"><div class="lazyload-wrapper "><div style="height:12rem" class="lazyload-placeholder"></div></div></a></div><div class="flex-1 bg-white p-6 flex flex-col justify-between"><div class="flex-1"><p class="text-sm leading-5 font-medium text-primary">Article</p><a class="block hover:no-underline" href="/reading-and-writing-csv-in-bash/"><h3 class="mt-2 text-xl leading-7 font-semibold text-gray-900 hover:underline">Reading and Writing CSV in Bash</h3><p class="mt-3 text-base leading-6 text-gray-500 break-words">Comma-Separated Values (CSV) is a widely used file format for storing data in tabular form, where each row represents a record and each column represents a field within that record. The values are separated by a comma, which is why the format is called CSV. CSV is a popular data...</p></a></div><div class="mt-6 flex items-center"><div class="flex-shrink-0"><a href="/author/stamd/"><div class="lazyload-wrapper "><div style="height:2.5rem" class="lazyload-placeholder"></div></div></a></div><div class="ml-3"><p class="text-sm leading-5 font-medium text-gray-900"><a href="/author/stamd/" class="hover:underline">Dimitrije Stamenic</a></p><div class="flex text-sm leading-5 text-gray-500"><time dateTime="2023-03-01">Mar 01, 2023</time><span class="mx-1">·</span><span>10<!-- --> min read</span></div></div></div></div></div></div><div><div class="flex flex-col rounded-lg shadow-lg overflow-hidden"><div class="flex-shrink-0"><a href="/how-to-convert-json-to-a-python-object/"><div class="lazyload-wrapper "><div style="height:12rem" class="lazyload-placeholder"></div></div></a></div><div class="flex-1 bg-white p-6 flex flex-col justify-between"><div class="flex-1"><p class="text-sm leading-5 font-medium text-primary">Article</p><a class="block hover:no-underline" href="/how-to-convert-json-to-a-python-object/"><h3 class="mt-2 text-xl leading-7 font-semibold text-gray-900 hover:underline">How to Convert JSON to a Python Object</h3><p class="mt-3 text-base leading-6 text-gray-500 break-words">In the world of programming, data is often stored and transmitted in various formats to other parts of an application or other web services. To fascillitate data transfer between services written in different languages and frameworks (such as a Java backend communicating with a Python service, and sending the results...</p></a></div><div class="mt-6 flex items-center"><div class="flex-shrink-0"><a href="/author/stamd/"><div class="lazyload-wrapper "><div style="height:2.5rem" class="lazyload-placeholder"></div></div></a></div><div class="ml-3"><p class="text-sm leading-5 font-medium text-gray-900"><a href="/author/stamd/" class="hover:underline">Dimitrije Stamenic</a></p><div class="flex text-sm leading-5 text-gray-500"><time dateTime="2023-03-01">Mar 01, 2023</time><span class="mx-1">·</span><span>13<!-- --> min read</span></div></div></div></div></div></div><div><div class="flex flex-col rounded-lg shadow-lg overflow-hidden"><div class="flex-shrink-0"><a href="/guide-to-order-by-clause-in-mysql/"><div class="lazyload-wrapper "><div style="height:12rem" class="lazyload-placeholder"></div></div></a></div><div class="flex-1 bg-white p-6 flex flex-col justify-between"><div class="flex-1"><p class="text-sm leading-5 font-medium text-primary">Article</p><a class="block hover:no-underline" href="/guide-to-order-by-clause-in-mysql/"><h3 class="mt-2 text-xl leading-7 font-semibold text-gray-900 hover:underline">Guide to the ORDER BY Clause in MySQL</h3><p class="mt-3 text-base leading-6 text-gray-500 break-words">MySQL is a popular open-source database management system that is widely used in web applications. One of the fundamental tasks in working with MySQL is querying data from tables. The ORDER BY clause is a key feature of MySQL queries that enables you to sort the result set based on...</p></a></div><div class="mt-6 flex items-center"><div class="flex-shrink-0"><a href="/author/stamd/"><div class="lazyload-wrapper "><div style="height:2.5rem" class="lazyload-placeholder"></div></div></a></div><div class="ml-3"><p class="text-sm leading-5 font-medium text-gray-900"><a href="/author/stamd/" class="hover:underline">Dimitrije Stamenic</a></p><div class="flex text-sm leading-5 text-gray-500"><time dateTime="2023-03-01">Mar 01, 2023</time><span class="mx-1">·</span><span>15<!-- --> min read</span></div></div></div></div></div></div><div><div class="flex flex-col rounded-lg shadow-lg overflow-hidden"><div class="flex-shrink-0"><a href="/what-does-2-1-do-on-the-command-line/"><div class="lazyload-wrapper "><div style="height:12rem" class="lazyload-placeholder"></div></div></a></div><div class="flex-1 bg-white p-6 flex flex-col justify-between"><div class="flex-1"><p class="text-sm leading-5 font-medium text-primary">Article</p><a class="block hover:no-underline" href="/what-does-2-1-do-on-the-command-line/"><h3 class="mt-2 text-xl leading-7 font-semibold text-gray-900 hover:underline">What Does "2>&1" do on the Command Line?</h3><p class="mt-3 text-base leading-6 text-gray-500 break-words">The command line is a powerful tool for developers and system administrators. It allows them to perform tasks quickly and efficiently, without having to rely on graphical user interfaces. Understanding the basic concepts of the command line, such as redirections, is essential for unlocking its full potential. One of these...</p></a></div><div class="mt-6 flex items-center"><div class="flex-shrink-0"><a href="/author/stamd/"><div class="lazyload-wrapper "><div style="height:2.5rem" class="lazyload-placeholder"></div></div></a></div><div class="ml-3"><p class="text-sm leading-5 font-medium text-gray-900"><a href="/author/stamd/" class="hover:underline">Dimitrije Stamenic</a></p><div class="flex text-sm leading-5 text-gray-500"><time dateTime="2023-01-10">Jan 10, 2023</time><span class="mx-1">·</span><span>6<!-- --> min read</span></div></div></div></div></div></div><div><div class="flex flex-col rounded-lg shadow-lg overflow-hidden"><div class="flex-shrink-0"><a href="/how-to-grep-recursively-in-bash/"><div class="lazyload-wrapper "><div style="height:12rem" class="lazyload-placeholder"></div></div></a></div><div class="flex-1 bg-white p-6 flex flex-col justify-between"><div class="flex-1"><p class="text-sm leading-5 font-medium text-primary">Article</p><a class="block hover:no-underline" href="/how-to-grep-recursively-in-bash/"><h3 class="mt-2 text-xl leading-7 font-semibold text-gray-900 hover:underline">How to Grep Recursively in Bash</h3><p class="mt-3 text-base leading-6 text-gray-500 break-words">Grep is a powerful tool in the Unix world that allows you to search for specific text within files or even directories. It is widely used for log analysis, code review, and many other tasks that require searching for text. In Bash, you can use grep to search for specific...</p></a></div><div class="mt-6 flex items-center"><div class="flex-shrink-0"><a href="/author/stamd/"><div class="lazyload-wrapper "><div style="height:2.5rem" class="lazyload-placeholder"></div></div></a></div><div class="ml-3"><p class="text-sm leading-5 font-medium text-gray-900"><a href="/author/stamd/" class="hover:underline">Dimitrije Stamenic</a></p><div class="flex text-sm leading-5 text-gray-500"><time dateTime="2023-01-09">Jan 09, 2023</time><span class="mx-1">·</span><span>9<!-- --> min read</span></div></div></div></div></div></div><div><div class="flex flex-col rounded-lg shadow-lg overflow-hidden"><div class="flex-shrink-0"><a href="/how-to-get-the-source-directory-of-a-bash-script/"><div class="lazyload-wrapper "><div style="height:12rem" class="lazyload-placeholder"></div></div></a></div><div class="flex-1 bg-white p-6 flex flex-col justify-between"><div class="flex-1"><p class="text-sm leading-5 font-medium text-primary">Article</p><a class="block hover:no-underline" href="/how-to-get-the-source-directory-of-a-bash-script/"><h3 class="mt-2 text-xl leading-7 font-semibold text-gray-900 hover:underline">How to Get the Source Directory of a Bash Script</h3><p class="mt-3 text-base leading-6 text-gray-500 break-words">Getting the source directory of a Bash script is an important topic for anyone who is looking to develop robust and reliable Bash scripts. Understanding how to retrieve the source directory of a script can make it easier to manage and organize your code. Whether you're a beginner or an...</p></a></div><div class="mt-6 flex items-center"><div class="flex-shrink-0"><a href="/author/stamd/"><div class="lazyload-wrapper "><div style="height:2.5rem" class="lazyload-placeholder"></div></div></a></div><div class="ml-3"><p class="text-sm leading-5 font-medium text-gray-900"><a href="/author/stamd/" class="hover:underline">Dimitrije Stamenic</a></p><div class="flex text-sm leading-5 text-gray-500"><time dateTime="2023-01-06">Jan 06, 2023</time><span class="mx-1">·</span><span>5<!-- --> min read</span></div></div></div></div></div></div></div><div class="mt-8 border-t border-gray-200 px-4 flex items-center justify-between sm:px-0"><div class="-mt-px w-0 flex-1 flex justify-end"><a class="border-t-2 border-transparent pt-4 pl-1 inline-flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300" href="/author/david/page/2/">Next<svg class="ml-3 h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></a></div></div></div></div></div></main><div class="bg-white border-t border-gray-300"><div class="max-w-screen-xl mx-auto pt-12 pb-6 px-4 sm:px-6 md:flex md:items-center md:justify-between lg:px-8"><div class="flex justify-center md:order-2"><a href="https://twitter.com/stackabuse" target="_blank" rel="noreferrer noopener" class="text-gray-500 hover:text-twitter"><span class="sr-only">Twitter</span><svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24"><path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84"></path></svg></a><a href="https://github.com/stackabuse" target="_blank" rel="noreferrer noopener" class="ml-6 text-gray-500 hover:text-github"><span class="sr-only">GitHub</span><svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"></path></svg></a><a href="https://www.facebook.com/stackabuse" target="_blank" rel="noreferrer noopener" class="ml-6 text-gray-500 hover:text-facebook"><span class="sr-only">Facebook</span><svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M22 12c0-5.523-4.477-10-10-10S2 6.477 2 12c0 4.991 3.657 9.128 8.438 9.878v-6.987h-2.54V12h2.54V9.797c0-2.506 1.492-3.89 3.777-3.89 1.094 0 2.238.195 2.238.195v2.46h-1.26c-1.243 0-1.63.771-1.63 1.562V12h2.773l-.443 2.89h-2.33v6.988C18.343 21.128 22 16.991 22 12z" clip-rule="evenodd"></path></svg></a></div><div class="mt-8 md:mt-0 md:order-1"><p class="text-center text-base leading-6 text-gray-500">© 2013-<!-- -->2025<!-- --> Stack Abuse. All rights reserved.</p><div class="text-sm"><a href="/about" class="pr-4 text-gray-500 border-r-2 border-grey-400 hover:no-underline hover:text-gray-600">About</a><a href="/disclosure" class="px-4 text-gray-500 border-r-2 border-grey-400 hover:no-underline hover:text-gray-600">Disclosure</a><a href="/privacy-policy" class="px-4 text-gray-500 border-r-2 border-grey-400 hover:no-underline hover:text-gray-600">Privacy</a><a href="/terms-of-service" class="pl-4 text-gray-500 hover:no-underline hover:text-gray-600">Terms</a><div id="ccpa" style="display:none;cursor:pointer">Do not share my Personal Information.</div></div></div></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"author":{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","contents":[{"id":1169,"title":"Introduction to Django","slug":"introduction-to-django","body_html":"\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eDjango is one of today's most widely-used Python web frameworks. For now, we will not focus on the technical definition of a web framework - the guide includes a section dedicated to explaining what frameworks are and what they do - but rather consider the literal meaning of the word, as it does not deviate much in this context.\u003c/p\u003e\n\u003cp\u003eDjango's role is to provide structure (as this is what a framework does) for Python applications designed for the web (hence the \u003cem\u003eweb\u003c/em\u003e framework). Additionally, Django offers utility functions and modules that encapsulate and streamline the tedious details of web development, creating a second layer of abstraction on top of Python.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIn this guide, we will explore the workings of Django and become familiar with its architecture, features, and use cases. We will also touch on how the web and web frameworks function while explaining Django's place in this system.\u003c/p\u003e\n\u003c/blockquote\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e Before diving into Django, we strongly recommend familiarizing yourself with certain technologies/concepts.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eThe first requirement to start programming with Django is having basic Python knowledge, given that Django itself is built on Python. However, if you have experience with \u003cem\u003eany\u003c/em\u003e Object-Oriented language, you should be able to follow this particular guide.\u003c/p\u003e\n\u003cp\u003eThe second requirement is having HTML knowledge, as it is the most common way to structure web pages.\u003c/p\u003e\n\u003cp\u003eThe final requirement is understanding basic relational database theory - comprehending how databases are structured and how pieces of data relate to one another. (SQL knowledge is also quite helpful, but not necessary.)\u003c/p\u003e\n\u003ch2 id=\"howdoesthewebwork\"\u003eHow does the web work?\u003c/h2\u003e\n\u003cp\u003eThe Internet defines the means by which we exchange various types of data between numerous computers. This exchange has two endpoints: a client and a server. A client refers to the computer that is on the receiving end of this data exchange, while a server is the keeper and handler of the content to be distributed.\u003c/p\u003e\n\u003cp\u003eThis \u003cem\u003econtent\u003c/em\u003e, in the early days of the Internet, was a static file sitting somewhere on the server's file system. A URL, then, defined the literal path to this static file, and when input into a browser, it displayed the exact same page at any point in time. Today, our web pages are dynamic and in constant interaction with their users. The server is no longer simply a storage unit for static files; it encompasses the business logic that renders the webpage along with the webpage's state at any particular moment in time.\u003c/p\u003e\n\u003cp\u003eThe interaction between the client and the server is conducted via HTTP (Hypertext Transfer Protocol). Any time a web address is input into a browser, the browser sends an \u003cem\u003eHTTP request\u003c/em\u003e to the server, asking for the webpage at the given address. The server then analyzes this request and returns an \u003cem\u003eHTTP response\u003c/em\u003e. Although there are certain technical details to both, in essence, a request encodes an attempt to interact with a given webpage, and a response tells the browser what this attempt resulted in on the server-side.\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/introduction-to-django-1.png\" alt=\"request response\"\u003e\u003c/p\u003e\n\u003cp\u003eA request carries within it a method along with an identifier as to where in the specified domain the method would be applied. For you to see this article, for example, your browser sent a \u003ccode\u003eGET\u003c/code\u003e request (the method) to \u003ccode\u003e/introduction-to-django\u003c/code\u003e (the identifier) on \u003ccode\u003estackabuse.com\u003c/code\u003e (the domain). There are numerous HTTP request methods to accommodate the browser's attempts to fetch information and possibly add or manipulate data (\u003ccode\u003eGET\u003c/code\u003e, \u003ccode\u003ePOST\u003c/code\u003e, \u003ccode\u003ePUT\u003c/code\u003e, \u003ccode\u003eDELETE\u003c/code\u003e, \u003ccode\u003eTRACE\u003c/code\u003e, etc.). The response, on the other hand, includes a 3-digit status code and the source code of the webpage to be rendered. Various status codes indicate different types of error, success, and redirection (i.e., the code \u003ccode\u003e200\u003c/code\u003e means the request was successful, \u003ccode\u003e201\u003c/code\u003e means the request was successful \u003cem\u003eand\u003c/em\u003e it created a new resource).\u003c/p\u003e\n\u003ch3 id=\"djangosroleinthissystem\"\u003eDjango's Role in This System\u003c/h3\u003e\n\u003cp\u003eWe label the processes that run on two different ends of the communication discussed above as \u003cem\u003efrontend\u003c/em\u003e and \u003cem\u003ebackend\u003c/em\u003e. Frontend refers to the client-side processes, while backend covers the server-side.\u003c/p\u003e\n\u003cp\u003eFrontend \u003cem\u003edevelopment\u003c/em\u003e concerns itself with how the data is rendered and displayed \u003cem\u003eafter\u003c/em\u003e it is received on the client's end. Backend development, on the other hand, focuses on serving the website, accomplishing its dynamic characteristics, and calculating and managing its ever-changing state.\u003c/p\u003e\n\u003cp\u003eDjango is a full-stack framework, meaning that it provides the tools to handle both the frontend and backend of a web application. On the frontend, Django defines the presentation logic. It employs keywords and methods to attach data to certain places, modify their appearance in specific ways, and move them around if necessary.\u003c/p\u003e\n\u003cp\u003eOn the backend, Django handles the request/response cycle. Django processes the requests when they reach the server and renders them according to the logic defined for that particular website. It then manipulates the database if necessary, applies the business logic, and creates the context to be returned to the frontend (aka the response).\u003c/p\u003e\n\u003ch2 id=\"whatisawebframework\"\u003eWhat is a Web Framework?\u003c/h2\u003e\n\u003cp\u003eWe have Python, a general-purpose programming language whose job is to construct behavior that can be executed by a computer. Building command-line interface applications, creating GUIs (graphical user interfaces), games, or web apps are all included in Python's job description, and you most certainly \u003cem\u003ecan\u003c/em\u003e accomplish these tasks with raw Python. Then, why do we need Django, an additional technology on top of Python? Why should we even bother learning it?\u003c/p\u003e\n\u003cp\u003eWell, Django itself is pure Python code. It actually includes most of the code you probably would have written yourself for a raw Python web application. That's what web frameworks do; they program the machinery that carries out typical web-application behavior, so the developers themselves don't have to.\u003c/p\u003e\n\u003cp\u003eInitially, Django will create the code infrastructure for our web application - the groundwork will be laid down by Django itself, and we will later code for additional behavior. Django will also provide shortcuts and conventions for \u003cem\u003ethe additional behavior\u003c/em\u003e and pack the time-consuming, boilerplate code into high-level abstractions.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e A \u003cem\u003eframework\u003c/em\u003e and a \u003cem\u003elibrary\u003c/em\u003e are both codebases; in general, a framework is a larger codebase. However, a framework differs from a library mainly in the sense that when a programmer uses a library, they pull the library into the project and call the behavior defined. When using a framework, there is an inversion of control; the framework itself defines and manages the project, and what the programmer does is to tweak or add on to the behavior defined by the framework.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eUsing a web framework saves programmers a lot of effort and time. In addition to that, there is also the benefit of frameworks being used by large communities. Django has been around for over 15 years, and many popular websites currently run on Django. It is used, tested, approved, criticized, and improved upon (given that it is an open-source project) by many. It is more stable and secure than what any one person can come up with on a random afternoon.\u003c/p\u003e\n\u003ch2 id=\"djangosstructure\"\u003eDjango's Structure\u003c/h2\u003e\n\u003cp\u003eFurther down the guide, we will see how to install Django and how to set up our project. Before diving into the code, however, let's take a gander at how Django projects are structured, and thus, how we are supposed to structure our code.\u003c/p\u003e\n\u003cp\u003eDjango's project structure may seem slightly convoluted at first glance. When we initiate our project and create our first app, we will be presented with an admittedly overwhelming number of files. Each of these files contains a certain functionality or code for a specific aspect of the project. The web application at the end will result from the combined effort of these various pieces.\u003c/p\u003e\n\u003cp\u003eWe have mentioned that Django, on the server-side, takes in requests, applies the logic defined for the specific webpage, interacts with the database if necessary (if the user is trying to delete, add, or edit content), and sends back a response. On the user's end, the response arrives carrying a message and the source code of the web page to be rendered. The rendering of the webpage and the presentation of the data is also part of Django's job.\u003c/p\u003e\n\u003cp\u003eDjango divides this labor among three components: \u003cem\u003eviews\u003c/em\u003e, \u003cem\u003emodels\u003c/em\u003e, and \u003cem\u003etemplates\u003c/em\u003e.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eViews make up the business logic. Each view is connected to a URL, and they define the behavior of the webpage located at that URL. The view processes requests that access the webpage, applies specific logic, and prepares the appropriate responses.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eModels create the database layer. They determine how data will be stored and accessed.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eTemplates establish the presentation logic. They decide the placement of data on the page and manage its appearance.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp\u003eEach of these layers will be defined in their own files and will be as loosely coupled as possible with one another. Modifications to any of these layers won't affect the others, and people working on one aspect won't necessarily need to know about the technical details of the other ones.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThink of the Django app as a small business, a scented soap shop. The shop has an owner; they make the executive decisions, choose whom to hire, which soaps to sell, and also pay the bills, the rent, and the taxes. This is our \u003cem\u003eview\u003c/em\u003e. The salesperson the owner employs is responsible for selling the soaps, keeping the shop clean and neat, and interacting with the customers. The executive decisions are not their concern, and since they are taking care of customer interactions, this load is off the owner's shoulders. Our salespeople are \u003cem\u003etemplates\u003c/em\u003e. The soaps the shop sells come from a supplier. The supplier is responsible for making the soaps, storing them, packing them, and shipping them. The owner only concerns themselves with which soaps to order, not with any single detail about how these soaps are made or how they end up at the shop. The supplier takes care of all this, and this is our \u003cem\u003emodel\u003c/em\u003e.\u003c/p\u003e\n\u003ch3 id=\"djangoapps\"\u003eDjango Apps\u003c/h3\u003e\n\u003cp\u003eDjango's convention is to group a project's different concerns in separate \u003cem\u003eapps\u003c/em\u003e (or \u003cem\u003eapplications\u003c/em\u003e). An \u003cem\u003eapp\u003c/em\u003e in Django terms is a bundle of code devoted to performing a single task for the website (an ecommerce website's product listing, buyer, and seller portals can each define an app). Each app can have its own models, views, and templates, but it does not necessarily have to employ any one of them. Apps are meant to be relatively self-contained and potentially portable (so that they can be plugged into different projects).\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIf we were to follow the small business analogy, a Django project would be a shopping mall that houses many small businesses - the apps.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eDividing a Django project into apps is an individual process; there is no right or wrong way of doing it. A programmer may choose to create fifteen apps or only one app. They may opt to write them all from scratch or incorporate third-party apps to carry out certain functionalities. Although it may not be the wisest decision, a programmer can also go rogue and decide not to use any apps.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote\u003c/strong\u003e: There is only one hard-set rule regarding the app convention: models can only be defined and used within apps.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eWe will follow the convention and the default structure Django provides for us. We will be coding for a small section of a puppy adoption website to demonstrate the workings of views, templates, and models.\u003c/p\u003e\n\u003cp\u003eIf at this moment, you feel a little flustered and don't quite understand where each piece goes, don't worry. We will apply a second coat and refine these concepts. In the end, hopefully, it will all be quite clear.\u003c/p\u003e\n\u003ch2 id=\"djangosetup\"\u003eDjango Set Up\u003c/h2\u003e\n\u003ch3 id=\"installingpython\"\u003eInstalling Python\u003c/h3\u003e\n\u003cp\u003eDjango is written in Python, so the first requirement to start coding with Django is having Python installed.\u003c/p\u003e\n\u003cp\u003eLet's go to the \u003ca rel=\"nofollow noopener\" target=\"_blank\" href=\"https://www.python.org\"\u003eofficial website\u003c/a\u003e to download the Python installer. Once we hover the cursor over the 'Downloads' tab in the navigation bar, the website will provide us with the appropriate installer for our system.\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/introduction-to-django-2.png\" alt=\"python.org\"\u003e\u003c/p\u003e\n\u003cp\u003eClick the version suggested and open the installer once the download is complete.\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/introduction-to-django-3.png\" alt=\"python installer\"\u003e\u003c/p\u003e\n\u003cp\u003eOn Mac and Linux, you can click 'Install Now' and follow through with the installer without changing any default settings. On Windows systems, however, before hitting \u0026quot;\u003cem\u003eInstall Now\u003c/em\u003e\u0026quot;, we need to check the box to \u0026quot;\u003cem\u003eAdd Python to PATH\u003c/em\u003e\u0026quot;.\u003c/p\u003e\n\u003ch3 id=\"virtualenvironmentsetup\"\u003eVirtual Environment Setup\u003c/h3\u003e\n\u003cp\u003ePython has a somewhat inconvenient approach towards third-party packages. All third-party Python libraries, regardless of the project they are intended for, are stored in the same location by default without proper organization. If you work with Python long enough, this characteristic can lead to chaos.\u003c/p\u003e\n\u003cp\u003eTo resolve this issue, we use virtual environments for Python projects. We create an isolated Python environment for each individual project and install the project's dependencies in that environment. This not only helps categorize third-party packages but also prevents projects' dependencies from colliding with each other.\u003c/p\u003e\n\u003cp\u003eSince Django is also a third-party Python package, we will be installing it within a virtual environment. Let's go ahead and start by creating a new directory to place our virtual environment.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e mkdir django-intro\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eYou can name this directory whatever you want, though it is important that the path to your virtual environment does not include any spaces, as this may cause errors while executing certain commands.\u003c/p\u003e\n\u003cp\u003eInside the directory we've just created, run:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e#\u003c/span\u003e\u003cspan class=\"bash\"\u003e Switch directory to django-intro\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e \u003cspan class=\"hljs-built_in\"\u003ecd\u003c/span\u003e django_intro\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e\n#\u003c/span\u003e\u003cspan class=\"bash\"\u003e Create the virtual environment on Windows\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e python -m venv ./myenv\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e\n#\u003c/span\u003e\u003cspan class=\"bash\"\u003e Create the virtual environment on Linux/Mac\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e python3 -m venv ./myenv\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e On Mac and Linux systems, there might already be an older version of Python installed. Because of this, when creating the virtual environment, you have to specify which Python version to use (hence \u003ccode\u003epython3 -m venv ./myenv\u003c/code\u003e). After creating the virtual environment, you can simply use the keyword \u003ccode\u003epython\u003c/code\u003e since the environment is built on, and therefore only knows of, one specific version of Python.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eNow that our virtual environment has been created, all that's left to do is activate it by running the \u003ccode\u003eactivate\u003c/code\u003e script:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e#\u003c/span\u003e\u003cspan class=\"bash\"\u003e on Windows \u003cspan class=\"hljs-built_in\"\u003ecommand\u003c/span\u003e prompt\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e .\\myenv\\Scripts\\activate.bat\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e\n#\u003c/span\u003e\u003cspan class=\"bash\"\u003e on Linux\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e \u003cspan class=\"hljs-built_in\"\u003esource\u003c/span\u003e myenv/Scripts/activate\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e\n#\u003c/span\u003e\u003cspan class=\"bash\"\u003e on MacOS\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e \u003cspan class=\"hljs-built_in\"\u003esource\u003c/span\u003e myenv/bin/activate\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eOnce the environment is activated, if we install dependencies, they will only apply to that environment and won't conflict with other environments, including the system environment.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e You can use the command \u003ccode\u003edeactivate\u003c/code\u003e to leave the virtual environment.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eHere, we can install this environment's first package, Django, via \u003ccode\u003epip\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e(myenv) pip install \u003cspan class=\"hljs-string\"\u003e\u0026quot;Django==3.0.*\u0026quot;\u003c/span\u003e\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"startingoutwithdjango\"\u003eStarting Out with Django\u003c/h2\u003e\n\u003cp\u003eNow that we have Django installed, we can create our first Django project. While the virtual environment is still active (\u003ccode\u003e(myenv)\u003c/code\u003e next to the shell prompt indicates that it is), from the terminal, run:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e(myenv) django-admin startproject puppypound\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis command will instruct Django to create an initial structure for our project inside the directory we are working in. Let's open \u003ccode\u003edjango-intro/\u003c/code\u003e with a text editor and take a look at its contents.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003eThere are several text editors that are quite popular among programmers; you can perform a quick web search to find one you'd like. Visual Studio Code is one of them. It is free, easy to use, and provides nice visuals and certain functionalities to help with coding, testing, and debugging. You can download it through the \u003ca target=\"_blank\" href=\"https://code.visualstudio.com/\"\u003eofficial website\u003c/a\u003e and simply follow the installer to start coding with it.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e#\u003c/span\u003e\u003cspan class=\"bash\"\u003e To open the current working directory with VS Code\u003c/span\u003e\n\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e code .\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe will see that inside, along with the \u003ccode\u003evenv\u003c/code\u003e, a \u003ccode\u003epuppypound\u003c/code\u003e directory is created, the contents of which can be seen below.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003epuppypound/\n puppypound/\n __init__.py\n asgi.py\n settings.py\n urls.py\n wsgi.py\n manage.py\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWithin the \u003ccode\u003epuppypound\u003c/code\u003e, we have another directory with the same name, as well as the \u003ccode\u003emanage.py\u003c/code\u003e file. The \u003ccode\u003emanage.py\u003c/code\u003e file marks our project's \u003cem\u003eroot\u003c/em\u003e and provides us with a set of commands to interact with the project.\u003c/p\u003e\n\u003cp\u003eInside our second \u003ccode\u003epuppypound\u003c/code\u003e directory, there are several files listed; let's examine them.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e__init__.py\u003c/code\u003e is an empty file whose sole purpose is to indicate that the folder it resides in is a Python module. This file will not concern us, nor will we need to modify it in any way.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003easgi.py\u003c/code\u003e and \u003ccode\u003ewsgi.py\u003c/code\u003e files are related to deployment. Since this is an introductory guide, these files will not be of concern to us at the moment.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003esettings.py\u003c/code\u003e holds the configurations for our project, which we may modify or adjust from time to time.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eurls.py\u003c/code\u003e file defines the navigation system for our project. It lists the URLs of our website and associates each of them with a view.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eIf you think of a Django project as an electric circuit, the Django installation becomes the battery - the power that feeds the entire project. \u003ccode\u003esettings.py\u003c/code\u003e in this analogy is our copper wire connecting two different terminals of the battery. As long as the wire is stretched between the two terminals, there is current running, and technically we have an electric circuit. The same requirements need to be fulfilled to consider any Python package as a Django project: a wire and a battery - Django installation, and a settings file. And just like adding elements to the circuit by attaching them to the wire, we include the components that make up our project in the \u003ccode\u003esettings.py\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003esettings.py\u003c/code\u003e file holds information regarding the location of our project, the file defining our URL configuration (by default, it is the \u003ccode\u003eurls.py\u003c/code\u003e as we just discussed - but you can easily change that), the locations of our templates or static files, the configured database for the project, and so on. One important section of this file is:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003eINSTALLED_APPS = [\n \u0026#x27;django.contrib.admin\u0026#x27;,\n \u0026#x27;django.contrib.auth\u0026#x27;,\n \u0026#x27;django.contrib.contenttypes\u0026#x27;,\n \u0026#x27;django.contrib.sessions\u0026#x27;,\n \u0026#x27;django.contrib.messages\u0026#x27;,\n \u0026#x27;django.contrib.staticfiles\u0026#x27;,\n]\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe have mentioned before that conventionally, a Django project consists of various apps. These apps might be created from scratch, they may be third-party apps, or they can be brought in from Django's own \u003ccode\u003econtrib\u003c/code\u003e package. Regardless of the origin of their creators, to be a part of the project, each app should be listed in \u003ccode\u003eINSTALLED_APPS\u003c/code\u003e. As you can see above, the \u003ccode\u003estartproject\u003c/code\u003e command has already brought in some apps from \u003ccode\u003edjango.contrib\u003c/code\u003e.\u003c/p\u003e\n\u003ch3 id=\"djangocontrib\"\u003edjango.contrib\u003c/h3\u003e\n\u003cp\u003eDjango's codebase includes a \u003ccode\u003econtrib\u003c/code\u003e package; within this package, Django defines various add-ons to the core framework.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eThese sub-packages come bundled with Django to provide certain additional functionalities, though no part of the core framework is dependent on them (yet they may be dependent on each other).\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThe \u003ccode\u003econtrib\u003c/code\u003e package comprises 13 apps (at the time of writing):\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eadmin\u003c/code\u003e: an administrative interface\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eauth\u003c/code\u003e: user authentication system\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003econtenttypes\u003c/code\u003e: a high-level interface that manages models as \u003cem\u003econtent types\u003c/em\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eflatpages\u003c/code\u003e: Manages one-off static pages in the database\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003egis\u003c/code\u003e: Django's Geographic Information Systems support\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003ehumanize\u003c/code\u003e: Defines various template filters to \u003cem\u003ehumanize\u003c/em\u003e data\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003emessages\u003c/code\u003e: Enables cookie- and session-based messaging\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003epostgres\u003c/code\u003e: Provides additional PostgreSQL support\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003eredirects\u003c/code\u003e: Manages redirects\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003esessions\u003c/code\u003e: Django's session framework\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003esites\u003c/code\u003e: Connects multiple websites to a single database and Django configuration\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003esitemaps\u003c/code\u003e: Generates sitemap XML files\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003esyndication\u003c/code\u003e: Generates syndication feeds\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSome of these apps serve the basic needs of a website, such as authenticating users or managing content. However, some have rather cryptic descriptions. Each app requires a different level of knowledge and caters to various needs.\u003c/p\u003e\n\u003cp\u003eIn this guide, we will only experiment with the \u003ccode\u003eadmin\u003c/code\u003e app and leave the rest of the \u003ccode\u003econtrib\u003c/code\u003e apps for further guides to explore.\u003c/p\u003e\n\u003ch3 id=\"initiatinganapp\"\u003eInitiating an App\u003c/h3\u003e\n\u003cp\u003eBefore creating our first app, we will go ahead and start Django's development server to view our bare-bones website.\u003c/p\u003e\n\u003cp\u003eFrom the root, run the command:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e(myenv) python manage.py runserver\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn the terminal, you should see the output:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eSystem check identified no issues (0 silenced).\nDjango version 3.0.14, using settings \u0026#x27;puppypound.settings\u0026#x27;\nStarting development server at http://127.0.0.1:8000/\nQuit the server with CTRL-BREAK.\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e This terminal is now dedicated to handling the development server. We will keep the server running here and open a new terminal to execute commands.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eIf we go ahead and enter \u003ccode\u003ehttp://127.0.0.1:8000/\u003c/code\u003e into a browser, we'll see Django's welcome page.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e If we return to our editor now, we will see that a new file has appeared inside our root directory: \u003ccode\u003edb.sqlite3\u003c/code\u003e. This is the database file Django has created according to our \u003ccode\u003esettings.py\u003c/code\u003e. By default, Django projects are configured to use SQLite, a lightweight mock-up database. However, SQLite is not intended for production. We will be using it in this guide for educational purposes.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eAt this point, we have a working website - \u003cem\u003etheoretically\u003c/em\u003e. Let's add some functionality to it. We will create an app of our own within which we will code some machinery. Inside our new terminal, we activate the virtual environment, switch into our project directory (\u003ccode\u003epuppypound\u003c/code\u003e), and run:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e(myenv) django-admin startapp listing\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis command will create a new folder named \u003ccode\u003elisting\u003c/code\u003e in our project's root. Within \u003ccode\u003elisting/\u003c/code\u003e, we see Django's default app structure created:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003elisting/\n __init__.py\n admin.py\n apps.py\n migrations/\n __init__.py\n models.py\n tests.py\n views.py\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003eapps.py\u003c/code\u003e is the configuration file for our application - we will not change its default state; we will accept it as is throughout this guide. For the rest of the files (except \u003ccode\u003etests.py\u003c/code\u003e, which is where we are supposed to create tests for our app), we will provide explanations further down.\u003c/p\u003e\n\u003cp\u003eFor now, let's register our app in the \u003ccode\u003epuppypound/settings.py\u003c/code\u003e file by adding it to the list of \u003ccode\u003eINSTALLED_APPS\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003eINSTALLED_APPS = [\n \u0026#x27;listing\u0026#x27;,\n \u0026#x27;django.contrib.admin\u0026#x27;,\n \u0026#x27;django.contrib.auth\u0026#x27;,\n \u0026#x27;django.contrib.contenttypes\u0026#x27;,\n \u0026#x27;django.contrib.sessions\u0026#x27;,\n \u0026#x27;django.contrib.messages\u0026#x27;,\n \u0026#x27;django.contrib.staticfiles\u0026#x27;,\n]\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAwesome!\u003c/p\u003e\n\u003ch2 id=\"models\"\u003eModels\u003c/h2\u003e\n\u003cp\u003eWe previously mentioned that Django applications' data access layers are built from \u003cem\u003emodels\u003c/em\u003e. A model is a Python object that extends the \u003ccode\u003edjango.db.models.Model\u003c/code\u003e class. Within this class, Django defines mechanisms to interact with the database and provides various methods that enable other parts of the application to communicate with the Model class. These capabilities are inherited by each child model, and all that is left for the programmer to do is define attributes to form an abstract data schema.\u003c/p\u003e\n\u003cp\u003eIn the background, Django maps each model to a database table. The attributes of these models are reflected as database columns, and the \u003cem\u003emodel fields\u003c/em\u003e assigned to these attributes determine the column types.\u003c/p\u003e\n\u003cp\u003eModel fields encode translations to SQL (Django creates appropriate SQL \u003ccode\u003eCREATE TABLE\u003c/code\u003e statements for each model), but this is not their only function. They define how the data will be represented in various parts of the application; we will see that soon enough.\u003c/p\u003e\n\u003cp\u003eLet's go ahead and start defining the data schema for our project. We will create two models: a \u003ccode\u003ePuppy\u003c/code\u003e and a \u003ccode\u003eShelter\u003c/code\u003e model. We will record the shelter's name and zip code information so that (even though we will not create this functionality in this guide) we can show visitors listings from shelters located in their region. Our \u003ccode\u003ePuppy\u003c/code\u003e model will hold the information we want to display in our listings for each puppy: the puppy's name, age, gender, and breed along with its adoption status, the date it was put up for adoption, and the shelter that posted the listing.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003emodels.py\u003c/code\u003e file of our app will look like this:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003efrom django.db import models\nfrom django.utils import timezone\n\n\nclass Shelter(models.Model):\n name = models.CharField(max_length=100)\n zip_code = models.CharField(max_length=10)\n\n\nclass Puppy(models.Model):\n STATUS_CHOICES = (\n (\u0026#x27;UFA\u0026#x27;, \u0026#x27;Up For Adoption\u0026#x27;),\n (\u0026#x27;ONHOLD\u0026#x27;, \u0026#x27;On Hold\u0026#x27;),\n )\n GENDER_CHOICES = (\n (\u0026#x27;F\u0026#x27;, \u0026#x27;Female\u0026#x27;),\n (\u0026#x27;M\u0026#x27;, \u0026#x27;Male\u0026#x27;),\n )\n name = models.CharField(max_length=100)\n age = models.CharField(max_length=2)\n breed = models.CharField(max_length=100)\n gender = models.CharField(max_length=1,\n choices=GENDER_CHOICES)\n status = models.CharField(max_length=10,\n choices=STATUS_CHOICES,\n default=\u0026#x27;UFA\u0026#x27;)\n shelter = models.ForeignKey(Shelter,\n on_delete=models.CASCADE)\n publish = models.DateTimeField(default=timezone.now)\n\n class Meta:\n ordering = (\u0026#x27;-publish\u0026#x27;,)\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eLet's break this down, line by line:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eWe start by importing the \u003ccode\u003emodels\u003c/code\u003e module from \u003ccode\u003edjango.db\u003c/code\u003e. This module defines Django's \u003ccode\u003eModel\u003c/code\u003e object, which will be extended by each model we create.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eWe also import the \u003ccode\u003etimezone\u003c/code\u003e object, which we will use to determine the time and date each listing was posted in a time zone-aware manner.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eOur \u003ccode\u003eShelter\u003c/code\u003e model extends \u003ccode\u003emodels.Model\u003c/code\u003e and has two attributes: \u003ccode\u003ename\u003c/code\u003e and \u003ccode\u003ezip_code\u003c/code\u003e, both of which are \u003ccode\u003eCharField\u003c/code\u003es. \u003ccode\u003eCharField\u003c/code\u003e corresponds to a VARCHAR field in the database and requires its \u003ccode\u003emax_length\u003c/code\u003e attribute to be defined. We use \u003ccode\u003eCharField\u003c/code\u003es for relatively small text; the shelter's \u003ccode\u003ename\u003c/code\u003e will consist of a maximum of 100 characters, while the \u003ccode\u003ezip_code\u003c/code\u003e is limited to 10.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFor the \u003ccode\u003eShelter\u003c/code\u003e model, Django will create a database table like this:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eCREATE\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eTABLE\u003c/span\u003e listing_shelter (\n \u0026quot;id\u0026quot; serial \u003cspan class=\"hljs-keyword\"\u003eNOT\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eNULL\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ePRIMARY\u003c/span\u003e KEY,\n \u0026quot;name\u0026quot; \u003cspan class=\"hljs-type\"\u003evarchar\u003c/span\u003e(\u003cspan class=\"hljs-number\"\u003e100\u003c/span\u003e) \u003cspan class=\"hljs-keyword\"\u003eNOT\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eNULL\u003c/span\u003e,\n \u0026quot;zip_code\u0026quot; \u003cspan class=\"hljs-type\"\u003evarchar\u003c/span\u003e(\u003cspan class=\"hljs-number\"\u003e10\u003c/span\u003e) \u003cspan class=\"hljs-keyword\"\u003eNOT\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eNULL\u003c/span\u003e\n);\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe name of the table is assigned by Django automatically, but it can be overridden. The \u003ccode\u003eid\u003c/code\u003e field is also assigned by Django. For each of the models defined, Django will create an auto-incrementing integer primary key field with the name \u003ccode\u003eid\u003c/code\u003e.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote\u003c/strong\u003e: This is an example syntax; Django will match the format of the SQL to the database backend defined in the project configurations.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cul\u003e\n\u003cli\u003eOur \u003ccode\u003ePuppy\u003c/code\u003e model begins by declaring two sets of \u003cem\u003echoices\u003c/em\u003e, one for the adoption status and one for the puppy's gender. \u003ccode\u003eSTATUS_CHOICES\u003c/code\u003e will be assigned to the \u003ccode\u003estatus\u003c/code\u003e field and restrict this \u003ccode\u003eCharField\u003c/code\u003e to the two values it holds, while \u003ccode\u003eGENDER_CHOICES\u003c/code\u003e will do the same for the \u003ccode\u003egender\u003c/code\u003e field.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp\u003eThe \u003ccode\u003echoices\u003c/code\u003e field option expects a sequence consisting of 2-tuples. The first element in the tuple is assigned to the attribute in question when selected, while the second value defines the human-readable name for display.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eThe \u003ccode\u003ename\u003c/code\u003e, \u003ccode\u003ebreed\u003c/code\u003e, and \u003ccode\u003eage\u003c/code\u003e fields are all \u003ccode\u003eCharField\u003c/code\u003es, and they are restricted to a certain number of characters using the \u003ccode\u003emax_length\u003c/code\u003e option.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eThe \u003ccode\u003egender\u003c/code\u003e field is also a \u003ccode\u003eCharField\u003c/code\u003e, but it cannot be filled with random values; it can either be assigned \u003ccode\u003eF\u003c/code\u003e or \u003ccode\u003eM\u003c/code\u003e, which will be displayed as \u003ccode\u003eFemale\u003c/code\u003e and \u003ccode\u003eMale\u003c/code\u003e, respectively.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eThe \u003ccode\u003estatus\u003c/code\u003e field, while also being restricted to a set of values, is additionally assigned a default value: \u003ccode\u003eUFA\u003c/code\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe \u003ccode\u003edefault\u003c/code\u003e field option is applicable to all field types. There are numerous field options available; the full list can be found in Django's \u003ca target=\"_blank\" href=\"https://docs.djangoproject.com/en/4.0/ref/models/fields/#field-options\"\u003emodel field reference documentation\u003c/a\u003e.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eThe \u003ccode\u003ePuppy\u003c/code\u003e model's \u003ccode\u003eshelter\u003c/code\u003e field defines a \u003cem\u003erelationship\u003c/em\u003e. Since each shelter can have multiple listings and each listing belongs to one shelter, we have a one-to-many relationship here, defined by a \u003ccode\u003eForeignKey\u003c/code\u003e field.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote\u003c/strong\u003e: Django defines model fields to indicate the three most common database relationships, namely: many-to-many, one-to-many, and one-to-one. All of these fields require their first argument to be a model class (the one that the model in question is relating to).\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e:::\u003c/p\u003e\n\u003cp\u003eAlong with the name of the model to be connected (\u003ccode\u003eShelter\u003c/code\u003e), our \u003ccode\u003eForeignKey\u003c/code\u003e field holds one other argument. The \u003ccode\u003eon_delete\u003c/code\u003e option is a required attribute; it tells Django what to do with a \u003ccode\u003ePuppy\u003c/code\u003e object if the connected \u003ccode\u003eShelter\u003c/code\u003e is deleted. We have assigned \u003ccode\u003eCASCADE\u003c/code\u003e to \u003ccode\u003eon_delete\u003c/code\u003e; \u003ccode\u003eCASCADE\u003c/code\u003e will delete every instance of the object in the case where the referenced object is deleted (meaning that \u003ccode\u003ePuppy\u003c/code\u003e objects will be deleted from the database if their connected \u003ccode\u003eShelter\u003c/code\u003e gets deleted).\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eThe \u003ccode\u003epublish\u003c/code\u003e field is a \u003ccode\u003eDateTimeField\u003c/code\u003e with a default value of \u003ccode\u003etimezone.now\u003c/code\u003e, which indicates the date and time the \u003ccode\u003ePuppy\u003c/code\u003e object is first created.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eThe inner class \u003ccode\u003eMeta\u003c/code\u003e defines the metadata for the model. Here, we have declared the default order to be descending according to publish time (\u003ccode\u003e-publish\u003c/code\u003e). When querying the \u003ccode\u003ePuppy\u003c/code\u003e objects, the \u003ccode\u003ePuppy\u003c/code\u003es that were put up for adoption most recently will be listed first.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp\u003eNow that we have created our data schema \u003cem\u003ein code\u003c/em\u003e, we need to tell Django that we want these changes applied to the database. Django uses \u003cem\u003emigrations\u003c/em\u003e to record these changes and later on applies these migrations to the database to sculpt it as defined in code.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eFirst, we will run the following command from the terminal:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e(myenv) python manage.py makemigrations\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eYou should see the output:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eMigrations for \u0026#x27;listing\u0026#x27;:\n listing\\migrations\\0001_initial.py\n - Create model Shelter\n - Create model Puppy\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis indicates that Django has noticed the changes we made in our \u003ccode\u003emodels.py\u003c/code\u003e file and created migrations for our two new models.\u003c/p\u003e\n\u003cp\u003eNow we will run:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e(myenv) python manage.py migrate\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis command will apply migrations for all the apps listed in \u003ccode\u003eINSTALLED_APPS\u003c/code\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eOperations to perform:\n Apply all migrations: admin, auth, contenttypes, listing, sessions\nRunning migrations:\n Applying contenttypes.0001_initial... OK\n Applying auth.0001_initial... OK\n Applying admin.0001_initial... OK\n Applying admin.0002_logentry_remove_auto_add... OK\n Applying admin.0003_logentry_add_action_flag_choices... OK\n Applying contenttypes.0002_remove_content_type_name... OK\n Applying auth.0002_alter_permission_name_max_length... OK\n Applying auth.0003_alter_user_email_max_length... OK\n Applying auth.0004_alter_user_username_opts... OK\n Applying auth.0005_alter_user_last_login_null... OK\n Applying auth.0006_require_contenttypes_0002... OK\n Applying auth.0007_alter_validators_add_error_messages... OK\n Applying auth.0008_alter_user_username_max_length... OK\n Applying auth.0009_alter_user_last_name_max_length... OK\n Applying auth.0010_alter_group_name_max_length... OK\n Applying auth.0011_update_proxy_permissions... OK\n Applying listing.0001_initial... OK\n Applying sessions.0001_initial... OK\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote\u003c/strong\u003e: Any changes to the \u003ccode\u003emodels.py\u003c/code\u003e require us to run \u003ccode\u003emakemigrations\u003c/code\u003e and \u003ccode\u003emigrate\u003c/code\u003e commands to be reflected in the database.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003ch2 id=\"admin\"\u003eAdmin\u003c/h2\u003e\n\u003cp\u003eDjango ships with a built-in admin interface. The admin handles user authentication, creates appropriate forms for data entry according to the models' structure, and validates data input based on field types. To manage the models through the admin interface, simply register them in the app's \u003ccode\u003eadmin.py\u003c/code\u003e file.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003estartapp\u003c/code\u003e command integrates Django admin into our project's structure, along with other apps and middleware the admin depends on. It also loads the URL patterns of the admin application into our project by default.\u003c/p\u003e\n\u003cp\u003eIf we open up our project's \u003ccode\u003eurls.py\u003c/code\u003e file, we will see:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e django.contrib \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e admin\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e django.urls \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e path\n\nurlpatterns = [\n path(\u003cspan class=\"hljs-string\"\u003e\u0026#x27;admin/\u0026#x27;\u003c/span\u003e, admin.site.urls),\n]\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe admin module is already imported, and the admin's URLs are appended to our project's domain with the 'admin/' prefix (\u003ccode\u003epath('admin/', admin.site.urls)\u003c/code\u003e).\u003c/p\u003e\n\u003cp\u003eLet's go ahead and register our models in \u003ccode\u003eadmin.py\u003c/code\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e django.contrib \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e admin\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e .models \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e Shelter, Puppy\n\nadmin.site.register(Shelter)\nadmin.site.register(Puppy)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe have imported our models from the same directory and registered each of them on the admin site. Now let's create a superuser to be able to log in to the site, with the command:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e(myenv) python manage.py createsuperuser\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe terminal will instruct us to fill in some information.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eUsername (leave blank to use 'username'): \nEmail address:\nPassword: \nPassword (again):\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAfter creating the superuser, if we go to \u003ccode\u003ehttp://127.0.0.1:8000/admin\u003c/code\u003e and log in with our superuser's credentials, we will see that \u003ccode\u003ePuppies\u003c/code\u003e and \u003ccode\u003eShelters\u003c/code\u003e are listed under the name \u003cem\u003eListing\u003c/em\u003e (our app's name).\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/introduction-to-django-4.png\" alt=\"django admin\"\u003e\u003c/p\u003e\n\u003cp\u003eIf we click on \u003ccode\u003ePuppies\u003c/code\u003e or \u003ccode\u003eShelters\u003c/code\u003e, we will be presented with empty lists since we haven't populated the database yet.\u003c/p\u003e\n\u003cp\u003eLet's go ahead and click the green \u003ccode\u003e+\u003c/code\u003e icon next to \u003ccode\u003ePuppies\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/introduction-to-django-5.png\" alt=\"add puppy\"\u003e\u003c/p\u003e\n\u003cp\u003eWe will be presented with an input form, each field of which is shaped and named according to the \u003ccode\u003ePuppy\u003c/code\u003e model we have defined. You can see that most of the \u003ccode\u003eCharField\u003c/code\u003es are assigned small text widgets, while the ones with \u003ccode\u003echoices\u003c/code\u003e defined have drop-down menus. The Status selection is prefixed with \u0026quot;Up For Adoption\u0026quot; - the assigned \u003ccode\u003edefault\u003c/code\u003e value. The JavaScript date-time picker corresponding to the \u003ccode\u003epublish\u003c/code\u003e field is also filled with the current date and time, as we declared in the model definition.\u003c/p\u003e\n\u003cp\u003eDjango has inspected our models and created a beautiful, easy-to-use interface for adding, deleting, or manipulating data, and we had to write exactly three lines of code to trigger this behavior.\u003c/p\u003e\n\u003ch2 id=\"interactingwithmodels\"\u003eInteracting with Models\u003c/h2\u003e\n\u003cp\u003eLet's return to our terminal to see how we can add, access, and manipulate data in code.\u003c/p\u003e\n\u003cp\u003eWe will first open up the Python shell with the command:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e(myenv) python manage.py shell\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cblockquote\u003e\n\u003cp\u003eWe are once again using the powers of \u003ccode\u003emanage.py\u003c/code\u003e here. This command not only provides us with an environment to execute Python code, but it also loads our project's settings; the Python shell that is triggered by \u003ccode\u003emanage.py\u003c/code\u003e is configured for our project.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eLet's go ahead and import the \u003ccode\u003elisting\u003c/code\u003e app's models into the terminal and start creating new instances for them.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003e\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e listing.models \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e Puppy, Shelter\n\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003eshelter = Shelter(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Senior Dog Rescue Center\u0026#x27;\u003c/span\u003e, zip_code=\u003cspan class=\"hljs-number\"\u003e12345\u003c/span\u003e)\n\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003eshelter.save()\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe have created a new instance of \u003ccode\u003eShelter\u003c/code\u003e and assigned it to the \u003ccode\u003eshelter\u003c/code\u003e variable. This does not affect the database just yet; this is simply a Python object stored in a variable. To transfer this piece of data to the database, we use the \u003ccode\u003esave()\u003c/code\u003e method on it. You can go ahead and reload \u003ccode\u003ehttp://127.0.0.1:8000/admin/listing/shelter/\u003c/code\u003e to see our new Shelter listed there.\u003c/p\u003e\n\u003cp\u003eLet's create another instance of Shelter, but this time, let's omit the middleman.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003eShelter(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Pupper Pound\u0026#x27;\u003c/span\u003e, zip_code=\u003cspan class=\"hljs-number\"\u003e2344\u003c/span\u003e).save()\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe can also use the model's \u003cem\u003emanager\u003c/em\u003e to create new instances. Each model is assigned a manager by default, and by default, this manager's name is \u003cem\u003eobjects\u003c/em\u003e. Managers' job is to manage the program's interactions with the specific database table.\u003c/p\u003e\n\u003cp\u003eManagers define a set of methods to retrieve, add, delete, or manipulate data. To trigger those methods, we use the syntax:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003emodel_name.manager_name.manager_method(method_arguments)\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e Django also gives programmers the option to assign custom managers to the models. These managers can have slightly modified ways of accessing, editing, and deleting data.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eTo add a new Shelter object through the Shelter's default manager, we execute:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003eShelter.objects.create(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Adoption Center\u0026#x27;\u003c/span\u003e, zip_code=\u003cspan class=\"hljs-number\"\u003e1111\u003c/span\u003e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe now have three Shelters on our list. Let's view them in the terminal.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003eShelter.objects.\u003cspan class=\"hljs-built_in\"\u003eall\u003c/span\u003e()\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode\u003eall()\u003c/code\u003e method of \u003ccode\u003eobjects\u003c/code\u003e lists all the elements of the related database table.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u0026lt;QuerySet [\u0026lt;Shelter: Senior Dog Rescue Center\u0026gt;, \u0026lt;Shelter: Pupper Pound\u0026gt;, \u0026lt;Shelter: Adoption Center\u0026gt;]\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eNow that we have some Shelters defined, let's go ahead and add some Puppies for adoption.\u003c/p\u003e\n\u003cp\u003eSince each Puppy is related to a Shelter, we will first retrieve the desired Shelter from the database, store it in a variable, and assign that variable to the \u003ccode\u003eshelter\u003c/code\u003e attribute of the new \u003ccode\u003ePuppy\u003c/code\u003e instance.\u003c/p\u003e\n\u003cp\u003eWe use the \u003ccode\u003eget()\u003c/code\u003e method of the manager to retrieve a single object and, to look up the desired instance, we feed it a value to match one of the model's attributes.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote\u003c/strong\u003e: The \u003ccode\u003eget()\u003c/code\u003e method is meant to fetch a single object from the database. If there is more than one value with the desired attribute, or none exists, the method will throw an error.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eWe will use the name attribute to retrieve a Shelter from the database.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003es1 = Shelter.objects.get(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Pupper Pound\u0026#x27;\u003c/span\u003e) \n\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003ePuppy.objects.create(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Diana\u0026#x27;\u003c/span\u003e, age=\u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e, breed=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Great Dane\u0026#x27;\u003c/span\u003e, gender=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;F\u0026#x27;\u003c/span\u003e, shelter=s1) \n\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003ePuppy.objects.create(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Tyson\u0026#x27;\u003c/span\u003e, age=\u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e, breed=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Pitbull Terrier\u0026#x27;\u003c/span\u003e, gender=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;M\u0026#x27;\u003c/span\u003e, shelter=s1) \n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe will create a few more Puppy instances and assign them to the rest of the shelters in the database.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003es2 = Shelter.objects.get(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Adoption Center\u0026#x27;\u003c/span\u003e)\n\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003ePuppy.objects.create(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Toraman\u0026#x27;\u003c/span\u003e, age=\u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e, breed=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Anatolian Shepherd\u0026#x27;\u003c/span\u003e, gender=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;M\u0026#x27;\u003c/span\u003e, shelter=s2) \n\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003ePuppy.objects.create(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Marquis\u0026#x27;\u003c/span\u003e, age=\u003cspan class=\"hljs-number\"\u003e7\u003c/span\u003e, breed=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Pitbull Terrier\u0026#x27;\u003c/span\u003e, gender=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;M\u0026#x27;\u003c/span\u003e, shelter=s2) \n\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003es3 = Shelter.objects.get(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Senior Dog Rescue Center\u0026#x27;\u003c/span\u003e) \n\u003cspan class=\"hljs-meta\"\u003e\u0026gt;\u0026gt;\u0026gt; \u003c/span\u003ePuppy.objects.create(name=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Roxanne\u0026#x27;\u003c/span\u003e, age=\u003cspan class=\"hljs-number\"\u003e11\u003c/span\u003e, breed=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Husky\u0026#x27;\u003c/span\u003e, gender=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;M\u0026#x27;\u003c/span\u003e, shelter=s3) \n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWhile creating the \u003ccode\u003ePuppy\u003c/code\u003e instances, we ignored the fields \u003ccode\u003estatus\u003c/code\u003e and \u003ccode\u003epublish\u003c/code\u003e since both of them have default values, and at this moment, the default values are appropriate.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e We covered the most basic ways to query the database, but there are numerous other methods. You can find them in the \u003ca rel=\"nofollow noopener\" target=\"_blank\" href=\"https://docs.djangoproject.com/en/4.0/topics/db/queries/\"\u003emaking queries documentation\u003c/a\u003e.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003ch2 id=\"urls\"\u003eURLs\u003c/h2\u003e\n\u003cp\u003eWe have built the bridge between our database and our program; now, we will create a webpage that utilizes this. Before creating the webpage, though, we need to define the URL it will reside at.\u003c/p\u003e\n\u003cp\u003eDjango's convention is to create the URL patterns at the app level and later \u003cem\u003einclude\u003c/em\u003e them in the project-level \u003ccode\u003eurls.py\u003c/code\u003e file (keeping the apps self-contained and portable if necessary).\u003c/p\u003e\n\u003cp\u003eLet's take another look at this file's contents:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003efrom django.contrib import admin\nfrom django.urls import path\n\nurlpatterns = [\n path(\u0026#x27;admin/\u0026#x27;, admin.site.urls),\n]\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eTo view the admin page, we visited \u003ccode\u003ehttp://127.0.0.1:8000/admin\u003c/code\u003e in our browser. This is the only pattern defined in this file: the path \u003ccode\u003eadmin/\u003c/code\u003e. We took a walk-through of the admin page, and when we tried to see the list of puppies, the browser directed us to \u003ccode\u003e/admin/listing/puppy/\u003c/code\u003e. When we wanted to add a puppy, we navigated to \u003ccode\u003e/admin/listing/puppy/add/\u003c/code\u003e. These are not explicitly defined at the project level. What the project level \u003ccode\u003eurls.py\u003c/code\u003e indicates is that there is a \u003cem\u003eset\u003c/em\u003e of URLs in this domain that starts with \u003ccode\u003eadmin/\u003c/code\u003e, and \u003ccode\u003eadmin.site.url\u003c/code\u003e will append the URLs of its various pages to this prefix. The \u003ccode\u003elisting/puppy\u003c/code\u003e and \u003ccode\u003elisting/puppy/add\u003c/code\u003e portions of the URLs are defined within the admin app.\u003c/p\u003e\n\u003cp\u003eWe will adhere to this convention and create a \u003ccode\u003eurls.py\u003c/code\u003e file inside our \u003ccode\u003elisting\u003c/code\u003e folder to hold our app-specific URL patterns.\u003c/p\u003e\n\u003cp\u003eEach URL pattern defined inside this file connects a view to a URL. When a browser requests a web page at one of these URLs, Django goes through the project's URL patterns, finds the assigned view, and instructs it to handle the incoming request. The view then processes the request and generates an appropriate response.\u003c/p\u003e\n\u003cp\u003eFirst, let's begin by registering our app-level URLs in the project's \u003ccode\u003eurls.py\u003c/code\u003e file.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003efrom django.urls import path, include\n\nurlpatterns = [\n path(\u0026#x27;admin/\u0026#x27;, admin.site.urls),\n path(\u0026#x27;listing/\u0026#x27;, include(listing.urls)),\n]\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe have imported \u003ccode\u003einclude\u003c/code\u003e from \u003ccode\u003edjango.urls\u003c/code\u003e and used this method inside \u003ccode\u003epath()\u003c/code\u003e to append all our app-level URLs to \u003ccode\u003elisting/\u003c/code\u003e.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003ccode\u003epath('admin/', admin.site.urls)\u003c/code\u003e is unique; to import all the other apps' URLs, we need to use the method \u003ccode\u003einclude()\u003c/code\u003e.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eInside \u003ccode\u003elisting/urls.py\u003c/code\u003e, type in:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003efrom django.urls import path\nfrom . import views\nurlpatterns = [\n path(\u0026#x27;\u0026#x27;, views.puppy_list),\n]\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eHere we have imported \u003ccode\u003epath\u003c/code\u003e from \u003ccode\u003edjango.urls\u003c/code\u003e, and the contents of our \u003ccode\u003eviews.py\u003c/code\u003e file.\u003c/p\u003e\n\u003cp\u003eIn our list of \u003ccode\u003eurlpatterns\u003c/code\u003e, we have defined a single URL: an empty string meaning that nothing will be appended to \u003ccode\u003elisting/\u003c/code\u003e. The \u003ccode\u003epuppy_list\u003c/code\u003e view (which we haven't created yet) will be triggered to render the home page of our app.\u003c/p\u003e\n\u003ch2 id=\"views\"\u003eViews\u003c/h2\u003e\n\u003cp\u003eA view is a function (there \u003cem\u003eare\u003c/em\u003e class-based views, but this is not our concern at the moment) that takes in a request, executes some arbitrary logic, and returns a response.\u003c/p\u003e\n\u003cp\u003eLet's go inside the \u003ccode\u003eviews.py\u003c/code\u003e file of our app to try and define a view:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003efrom django.shortcuts import render\nfrom django.http import HttpResponse\n\ndef puppy_list(request):\n return HttpResponse(\u0026#x27;Puppies\u0026#x27;)\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode\u003erender()\u003c/code\u003e method is imported by default at the app's creation. In addition to that, we have imported the \u003ccode\u003eHttpResponse\u003c/code\u003e class.\u003c/p\u003e\n\u003cp\u003eWe have created a standard Python function named \u003ccode\u003epuppy_list\u003c/code\u003e. What makes this function a \u003cem\u003eview\u003c/em\u003e is that its first argument is a \u003ccode\u003erequest\u003c/code\u003e object (naming this argument '\u003cem\u003erequest\u003c/em\u003e' is just the convention; there are no hard-set rules. You can name it '\u003cem\u003epotatoes\u003c/em\u003e' if you want; Django knows this function is a view - it is recorded in the URL patterns.) and it returns an \u003ccode\u003eHttpResponse\u003c/code\u003e.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eA \u003cem\u003eview\u003c/em\u003e is an abstract concept in Django; it is just a name conventionally used for the functions that handle the request-response cycle for a given URL. You are not bound to create your views inside the \u003ccode\u003eviews.py\u003c/code\u003e file either; you can create them in \u003ccode\u003epotatoes.py\u003c/code\u003e. As long as you import them into \u003ccode\u003eurls.py\u003c/code\u003e and assign them to a path, Django will know what they are meant to do. Notice that this was not the case for the models. Models needed to extend Django's \u003ccode\u003eModel\u003c/code\u003e class and they had to be defined inside the \u003ccode\u003emodels.py\u003c/code\u003e for Django to be able to keep track of them.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThe \u003ccode\u003epuppy_list\u003c/code\u003e view we have written is as simple as a view can get. We haven't incorporated any logic or database interactions - we have just passed a string to the \u003ccode\u003eHttpResponse()\u003c/code\u003e constructor.\u003c/p\u003e\n\u003cp\u003eIf we go to \u003ccode\u003ehttp://127.0.0.1:8000/listing/\u003c/code\u003e, we will see this string sitting alone at the top of the otherwise blank page.\u003c/p\u003e\n\u003cimg style=\"border: solid #aaaaaa 1px\" src=\"https://s3.stackabuse.com/media/articles/introduction-to-django-6.png\" /\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e If we go to \u003ccode\u003ehttp://127.0.0.1:8000/\u003c/code\u003e from the browser, we will no longer see the welcome page. We will encounter an error trying to reach the URL. The reason for this is that the welcome page is meant for newly created, empty projects. After we create a URL of our own, Django removes it, and since we haven't defined a URL pattern for this particular URL, we get an error trying to access it.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eOur intention with this page was to list the Puppy objects from our database. Let's go ahead and add logic to our view.\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003efrom .models import Puppy\n\ndef puppy_list(request):\n puppies = Puppy.objects.all()\n output = \u0026quot;, \u0026quot;.join([p.name + \u0026#x27; \u0026#x27; + p.age for p in puppies])\n return HttpResponse(output)\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe started by importing our \u003ccode\u003ePuppy\u003c/code\u003e model. Then, we used its manager's method \u003ccode\u003eall()\u003c/code\u003e to retrieve all instances of Puppy from the database. This query set is stored in \u003ccode\u003epuppies\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eWe used Python's \u003ccode\u003ejoin()\u003c/code\u003e to iterate over \u003ccode\u003epuppies\u003c/code\u003e and join each Puppy's information (\u003ccode\u003ep.name + ' ' + p.age\u003c/code\u003e) into a string with commas in between. We then passed this string into \u003ccode\u003eHttpResponse()\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eWhen we reload our page on the browser, we'll see that the text 'Puppies' is replaced with:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eRoxanne 11, Marquis 7, Toraman 3, Tyson 3, Diana 2\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis is more or less as far as we can go with a plain string. We generally use HTML in our response to help us structure the webpage on the frontend.\u003c/p\u003e\n\u003cp\u003eWe can define the HTML right here, assign it to a variable, and then return it as our response, but this might not be the best idea.\u003c/p\u003e\n\u003cp\u003eWe will use templates instead to separate the presentation logic into another file.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e We will be using Django's template language to create HTML, but it is capable of generating any text-based document (HTML, XML, CSV, etc.).\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003ch2 id=\"templates\"\u003eTemplates\u003c/h2\u003e\n\u003cp\u003eWithin our view, we have retrieved the data we want to return to the frontend. Now, we will fill this data into a template and render this template as an HTTP response.\u003c/p\u003e\n\u003cp\u003eDjango, by default, expects to find the templates of each app in a folder named \u003cem\u003etemplates\u003c/em\u003e within that app. Let's go ahead and create this folder for our \u003ccode\u003elisting\u003c/code\u003e app.\u003c/p\u003e\n\u003cp\u003eUnder \u003ccode\u003elisting/templates\u003c/code\u003e, we will create a \u003ccode\u003elist.html\u003c/code\u003e file and fill it with the following code:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003e\u003cspan class=\"hljs-meta\"\u003e\u0026lt;!DOCTYPE \u003cspan class=\"hljs-meta-keyword\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"hljs-tag\"\u003e\u0026lt;\u003cspan class=\"hljs-name\"\u003ehtml\u003c/span\u003e \u003cspan class=\"hljs-attr\"\u003elang\u003c/span\u003e=\u003cspan class=\"hljs-string\"\u003e\u0026quot;en\u0026quot;\u003c/span\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"hljs-tag\"\u003e\u0026lt;\u003cspan class=\"hljs-name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\n \u003cspan class=\"hljs-tag\"\u003e\u0026lt;\u003cspan class=\"hljs-name\"\u003emeta\u003c/span\u003e \u003cspan class=\"hljs-attr\"\u003echarset\u003c/span\u003e=\u003cspan class=\"hljs-string\"\u003e\u0026quot;UTF-8\u0026quot;\u003c/span\u003e\u0026gt;\u003c/span\u003e\n \u003cspan class=\"hljs-tag\"\u003e\u0026lt;\u003cspan class=\"hljs-name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003ePuppy Pound\u003cspan class=\"hljs-tag\"\u003e\u0026lt;/\u003cspan class=\"hljs-name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"hljs-tag\"\u003e\u0026lt;/\u003cspan class=\"hljs-name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"hljs-tag\"\u003e\u0026lt;\u003cspan class=\"hljs-name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\n \u003cspan class=\"hljs-tag\"\u003e\u0026lt;\u003cspan class=\"hljs-name\"\u003eh1\u003c/span\u003e\u0026gt;\u003c/span\u003ePuppies\u003cspan class=\"hljs-tag\"\u003e\u0026lt;/\u003cspan class=\"hljs-name\"\u003eh1\u003c/span\u003e\u0026gt;\u003c/span\u003e\n \u003c/span\u003e\u003cspan class=\"hljs-template-tag\"\u003e{% \u003cspan class=\"hljs-name\"\u003e\u003cspan class=\"hljs-name\"\u003efor\u003c/span\u003e\u003c/span\u003e puppy \u003cspan class=\"hljs-keyword\"\u003ein\u003c/span\u003e puppies|\u003cspan class=\"hljs-name\"\u003eslice\u003c/span\u003e:\u003cspan class=\"hljs-string\"\u003e\u0026quot;:3\u0026quot;\u003c/span\u003e %}\u003c/span\u003e\u003cspan class=\"xml\"\u003e\n \u003cspan class=\"hljs-tag\"\u003e\u0026lt;\u003cspan class=\"hljs-name\"\u003eh2\u003c/span\u003e\u0026gt;\u003c/span\u003e\n \u003c/span\u003e\u003cspan class=\"hljs-template-variable\"\u003e{{ puppy.name | upper }}\u003c/span\u003e\u003cspan class=\"xml\"\u003e\n \u003cspan class=\"hljs-tag\"\u003e\u0026lt;/\u003cspan class=\"hljs-name\"\u003eh2\u003c/span\u003e\u0026gt;\u003c/span\u003e\n \u003cspan class=\"hljs-tag\"\u003e\u0026lt;\u003cspan class=\"hljs-name\"\u003eh4\u003c/span\u003e\u0026gt;\u003c/span\u003e\n \u003c/span\u003e\u003cspan class=\"hljs-template-variable\"\u003e{{ puppy.age }}\u003c/span\u003e\u003cspan class=\"xml\"\u003e years old,\n \n \u003c/span\u003e\u003cspan class=\"hljs-template-variable\"\u003e{{ puppy.breed }}\u003c/span\u003e\u003cspan class=\"xml\"\u003e,\n \n \u003c/span\u003e\u003cspan class=\"hljs-template-tag\"\u003e{% \u003cspan class=\"hljs-name\"\u003e\u003cspan class=\"hljs-name\"\u003eif\u003c/span\u003e\u003c/span\u003e puppy.gender == \u0026#x27;F\u0026#x27; %}\u003c/span\u003e\u003cspan class=\"xml\"\u003e\n Female\n \u003c/span\u003e\u003cspan class=\"hljs-template-tag\"\u003e{% \u003cspan class=\"hljs-name\"\u003e\u003cspan class=\"hljs-name\"\u003eelse\u003c/span\u003e\u003c/span\u003e %}\u003c/span\u003e\u003cspan class=\"xml\"\u003e\n Male\n \u003c/span\u003e\u003cspan class=\"hljs-template-tag\"\u003e{% \u003cspan class=\"hljs-name\"\u003e\u003cspan class=\"hljs-name\"\u003eendif\u003c/span\u003e\u003c/span\u003e %}\u003c/span\u003e\u003cspan class=\"xml\"\u003e\n \u003cspan class=\"hljs-tag\"\u003e\u0026lt;/\u003cspan class=\"hljs-name\"\u003eh4\u003c/span\u003e\u0026gt;\u003c/span\u003e\n \u003cspan class=\"hljs-tag\"\u003e\u0026lt;\u003cspan class=\"hljs-name\"\u003ep\u003c/span\u003e\u0026gt;\u003c/span\u003e\n posted by \u003c/span\u003e\u003cspan class=\"hljs-template-variable\"\u003e{{ puppy.shelter.name }}\u003c/span\u003e\u003cspan class=\"xml\"\u003e, on \u003c/span\u003e\u003cspan class=\"hljs-template-variable\"\u003e{{ puppy.publish|\u003cspan class=\"hljs-name\"\u003edate\u003c/span\u003e:\u003cspan class=\"hljs-string\"\u003e\u0026quot;d M\u0026quot;\u003c/span\u003e }}\u003c/span\u003e\u003cspan class=\"xml\"\u003e \u003c/span\u003e\u003cspan class=\"hljs-template-variable\"\u003e{{ puppy.publish|\u003cspan class=\"hljs-name\"\u003etime\u003c/span\u003e:\u003cspan class=\"hljs-string\"\u003e\u0026quot;H:i\u0026quot;\u003c/span\u003e}}\u003c/span\u003e\u003cspan class=\"xml\"\u003e\n \u003cspan class=\"hljs-tag\"\u003e\u0026lt;/\u003cspan class=\"hljs-name\"\u003ep\u003c/span\u003e\u0026gt;\u003c/span\u003e\n \u003c/span\u003e\u003cspan class=\"hljs-template-tag\"\u003e{% \u003cspan class=\"hljs-name\"\u003e\u003cspan class=\"hljs-name\"\u003eendfor\u003c/span\u003e\u003c/span\u003e %}\u003c/span\u003e\u003cspan class=\"xml\"\u003e\n\u003cspan class=\"hljs-tag\"\u003e\u0026lt;/\u003cspan class=\"hljs-name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"hljs-tag\"\u003e\u0026lt;/\u003cspan class=\"hljs-name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eSo we have our regular HTML sitting in this file. Along with that, though, we have some peculiar expressions sprinkled in.\u003c/p\u003e\n\u003cp\u003eYou may have noticed a theme - there are three types of unusual syntax here:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFirst, we have \u003ccode\u003e{{ potatoes }}\u003c/code\u003e. Anything within two sets of curly braces defines a \u003cem\u003etemplate variable\u003c/em\u003e. These are placeholders; they mark where data is supposed to go. Each template variable gets evaluated according to the data that is passed into the template and gets replaced with an actual value.\u003c/li\u003e\n\u003cli\u003eThe ones with the structure \u003ccode\u003e{% do something %}\u003c/code\u003e are \u003cem\u003etemplate tags\u003c/em\u003e, and they have a rather broad definition: they do \u003cem\u003esomething\u003c/em\u003e; they trigger some arbitrary behavior.\u003c/li\u003e\n\u003cli\u003eLastly, we have pipe characters (\u003ccode\u003e|\u003c/code\u003e) appended to some variable names. This is Django's way of providing various alterations to the data's presentation. \u003ccode\u003e{{ variable | filter }}\u003c/code\u003e syntax evaluates the \u003ccode\u003evariable\u003c/code\u003e and modifies the data in the way \u003ccode\u003efilter\u003c/code\u003e defines.\u003c/li\u003e\n\u003c/ul\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e Even though Django template language has certain characteristics that resemble those of Python's, Django template language is \u003cem\u003enot\u003c/em\u003e Python merged with text. In fact, Python code is not welcome in templates. Python expressions will not get evaluated, and Python functions won't get executed inside a template.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eLet's go ahead and step through our code:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eWe created the regular HTML structure (if you are using VS Code, typing \u003ccode\u003ehtml:5\u003c/code\u003e and hitting enter will generate the boilerplate for you) and set 'Puppy Pound' as the \u003ccode\u003e\u0026lt;title\u0026gt;\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eAfter creating the \u003ccode\u003e\u0026lt;h1\u0026gt;\u003c/code\u003e element 'Puppies', we began looping over a list. We defined what would happen at each iteration between \u003ccode\u003e{% for %}\u003c/code\u003e and \u003ccode\u003e{% endfor %}\u003c/code\u003e tags.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003e{% for puppy in puppies|slice:\u0026quot;:3\u0026quot; %}\u003c/code\u003e includes a template filter \u003ccode\u003e|slice:\u0026quot;3\u0026quot;\u003c/code\u003e, which is a template filter that accepts an argument. \u003ccode\u003e|slice:\u0026quot;X\u0026quot;\u003c/code\u003e shortens the list in question to its first X elements, meaning that we will only loop over the first three \u003ccode\u003epuppy\u003c/code\u003e elements in \u003ccode\u003epuppies\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eNotice that we have not passed any data into this template yet. We assumed that we would be getting a list of \u003ccode\u003ePuppy\u003c/code\u003e objects and defined the presentation based on this assumption. We have named this hypothetical list \u003ccode\u003epuppies\u003c/code\u003e simply because it reflects what the list will contain. This is not the same \u003ccode\u003epuppies\u003c/code\u003e list we have defined in the \u003ccode\u003epuppy_list\u003c/code\u003e view.\u003c/p\u003e\n\u003cp\u003eFor each \u003ccode\u003epuppy\u003c/code\u003e, we first created an \u003ccode\u003e\u0026lt;h2\u0026gt;\u003c/code\u003e tag that holds \u003ccode\u003e{{ puppy.name | upper }}\u003c/code\u003e. The filter \u003ccode\u003e|upper\u003c/code\u003e will apply to the \u003ccode\u003epuppy\u003c/code\u003e's name and turn it into all uppercase.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003e\u0026lt;h4\u0026gt;\u003c/code\u003e tag we created next is meant to hold three different attributes of the \u003ccode\u003epuppy\u003c/code\u003e: its age, its breed, and its gender. We used an if-else clause to present the 'F' value as 'Female' and the 'M' as 'Male'. The end of the if-else clause is marked with \u003ccode\u003e{% endif %}\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eLastly, within a \u003ccode\u003e\u0026lt;p\u0026gt;\u003c/code\u003e tag, we placed the information regarding when the listing was put up and by which shelter. We used template filters to modify how the date and time will be displayed. In \u003ccode\u003e{{ puppy.publish|date:\u0026quot;d M\u0026quot; }}\u003c/code\u003e, \u003ccode\u003e|date:\u0026quot;d M\u0026quot;\u003c/code\u003e takes the date of our date-time field and displays its day (\u003ccode\u003ed\u003c/code\u003e) and month (\u003ccode\u003eM\u003c/code\u003e), while \u003ccode\u003e{{ puppy.publish|time:\u0026quot;H:i\u0026quot;}}\u003c/code\u003e formats the time of \u003ccode\u003epublish\u003c/code\u003e as \u003ccode\u003ehour:minute\u003c/code\u003e.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote\u003c/strong\u003e: You can look up all the other ways you can format date and time at \u003ca target=\"_blank\" rel=\"nofollow noopener\" href=\"https://docs.djangoproject.com/en/4.0/ref/templates/builtins/#date\"\u003eDjango's official website\u003c/a\u003e.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eNow all that is left to do is render this template as our webpage instead of a simple string.\u003c/p\u003e\n\u003cp\u003eLet's modify our \u003ccode\u003eviews.py\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"xml\"\u003edef puppy_list(request):\n puppies = Puppy.objects.all()\n return render(request,\n \u0026#x27;list.html\u0026#x27;,\n {\u0026#x27;puppies\u0026#x27;: puppies})\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAll we changed about \u003ccode\u003epuppy_list\u003c/code\u003e is what is returned from it. We used the \u003ccode\u003erender()\u003c/code\u003e method that is imported into this file by default.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003erender()\u003c/code\u003e takes in three arguments: the request object (if you have named the first argument of your view \u003ccode\u003epotatoes\u003c/code\u003e, you should place that in here), the path to the template to be rendered (since Django knows our templates are under the \u003ccode\u003elisting/templates/\u003c/code\u003e, we just put in \u003ccode\u003e'list.html'\u003c/code\u003e), and the \u003cem\u003econtext\u003c/em\u003e in the form of a dictionary. The keys in this dictionary define the names the template will use for the data (we put 'puppies' here because we assumed this would be the name when creating the template), and the values matched to these keys get passed into the template under these names.\u003c/p\u003e\n\u003cp\u003eNow, if we go to \u003ccode\u003ehttp://127.0.0.1:8000/listing/\u003c/code\u003e, our browser will send a request to this URL. Django will go through our URL patterns, find the URL the browser is looking for, and trigger the view function assigned to it. Our view, \u003ccode\u003epuppy_list\u003c/code\u003e, will interact with the database and retrieve all the \u003ccode\u003ePuppy\u003c/code\u003e instances into the variable \u003ccode\u003epuppies\u003c/code\u003e. It then will proceed to render \u003ccode\u003elist.html\u003c/code\u003e, filling it with the list of puppies. The template will place each puppy in its appropriate place, and at the end, the \u003ccode\u003erender()\u003c/code\u003e function will wrap it all up as an \u003ccode\u003eHttpResponse\u003c/code\u003e object and send it back to our browser.\u003c/p\u003e\n\u003cp\u003eWithin our browser, we will see something like this:\u003c/p\u003e\n\u003cimg style=\"border: solid #aaaaaa 1px\" src=\"https://s3.stackabuse.com/media/articles/introduction-to-django-7.png\" /\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eIn this guide, we have learned about Django: what it is, what it does, and how it works. We have observed that a Django project consists of various moving parts, and we examined the workings of each of them. However, this is an introductory guide, and its primary purpose is to familiarize you with Django's unique structure. There is still much to discover about each individual component.\u003c/p\u003e\n\u003cp\u003eIf you want to explore Django further, \u003cem\u003eDjango 3 By Example\u003c/em\u003e, by Antonio Melé, is an excellent book. For a deeper understanding of why Django works the way it does, you can also read \u003cem\u003eThe Definitive Guide to Django: Web Development Done Right\u003c/em\u003e (preferably the second edition) by Adrian Holovaty and Jacob Kaplan-Moss, two of the co-creators of Django. Although the Django version used in the book is deprecated (from years ago), it provides valuable insights into Django's structure.\u003c/p\u003e\n\u003cp\u003eIf you are looking for free resources, you can refer to Django's online documentation, which is well-written. You can also stay updated with the articles we post; there are already dozens of them on the website, and we are actively creating new ones.\u003c/p\u003e\n","parent_id":null,"type":"article","visibility":"public","img_feature":null,"is_featured":false,"locale":"en","custom_excerpt":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"comment_id":null,"og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"read_time_min":62,"published_at":1683288660000,"created_at":1639857278152,"updated_at":1704475625732,"tags":[{"id":9,"name":"python","slug":"python","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431358631000,"updated_at":1431358631000,"_pivot_content_id":1169,"_pivot_tag_id":9,"_pivot_sort_order":0},{"id":72,"name":"django","slug":"django","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1506009064000,"updated_at":1506009064000,"_pivot_content_id":1169,"_pivot_tag_id":72,"_pivot_sort_order":1},{"id":196,"name":"web development","slug":"web-development","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1601641448000,"updated_at":1601641448000,"_pivot_content_id":1169,"_pivot_tag_id":196,"_pivot_sort_order":2}],"contributors":[{"id":1,"name":"Scott Robinson","slug":"scott","role_id":1,"img_profile":"//s3.stackabuse.com/media/users/1922fc67b9d11d6364dc01a3d19f4293.jpg","img_cover":null,"bio_html":"","website":null,"location":"Omaha, NE","facebook":null,"twitter":"ScottWRobinson","github":"scottwrobinson","created_at":1431311293000,"updated_at":1676411663329,"role":"owner","_pivot_content_id":1169,"_pivot_user_id":1,"_pivot_role":"editor","_pivot_sort_order":2},{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","_pivot_content_id":1169,"_pivot_user_id":16,"_pivot_role":"editor","_pivot_sort_order":0},{"id":104,"name":"Cansın Güler","slug":"cansin","role_id":null,"img_profile":"/assets/images/logo-sa-small.png","img_cover":null,"bio_html":"","website":null,"location":null,"facebook":null,"twitter":null,"github":null,"created_at":1633366846997,"updated_at":1676493723353,"role":"author","_pivot_content_id":1169,"_pivot_user_id":104,"_pivot_role":"author","_pivot_sort_order":1}],"_pivot_user_id":16,"_pivot_content_id":1169},{"id":1694,"title":"Loading a Pretrained TensorFlow Model into TensorFlow Serving","slug":"loading-a-pretrained-tensorflow-model-into-tensorflow-serving","body_html":"\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eYou are part of a project that will use deep learning to try to identify what is in images - such as cars, ducks, mountains, sky, trees, etc.\u003c/p\u003e\n\u003cp\u003eIn this project, two things are important - the first one, is that the deep learning model trains quickly, with efficiency (because the model will be deployed to a device that doesn't have much computational power):\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eYour team has decided to use \u003ca href=\"https://arxiv.org/abs/2104.00298\" rel=\"nofollow noopener\" target=\"_blank\"\u003eEfficientNets\u003c/a\u003e, specifically, the V2 family, as they're robust, train fast, and have strong accuracy.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eAnd the second one is that the model needs to be accessible through a link, so predictions can be made in the web:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eRegarding the second point, you want to be able to make the model accessible to other people, in a way they could send their data through a \u003ca href=\"/the-python-requests-module/\" target=\"_blank\"\u003eREST API request\u003c/a\u003e and get the model predictions as a response. To do that, you need to deploy or serve a model, which can be done in a myriad of ways - though we'll be taking a look at with \u003ca href=\"https://www.tensorflow.org/tfx/guide/serving\" rel=\"nofollow noopener\" target=\"_blank\"\u003eTensorflow serving\u003c/a\u003e (TF Serving).\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eSo far so good, the first two project necessities are covered by EfficientNetV2 and TF Serving! In this guide, we'll be starting with a pre-trained model general image classifier and deploying it to TensorFlow Serving, using Docker.\u003c/p\u003e\n\u003ch2 id=\"tensorflowserving\"\u003eTensorFlow Serving\u003c/h2\u003e\n\u003cp\u003eTensorFlow Serving is, well, a serving system for machine learning models. It's specifically designed for production environments, and helps bridge the gap between data scientists and production-oriented software engineers.\u003c/p\u003e\n\u003cp\u003eYou can install it from source, which allows for customization (for specific use cases) or prioritize its integration to any operating system by utilizing \u003ca href=\"https://www.docker.com/resources/what-container/\" rel=\"nofollow noopener\" target=\"_blank\"\u003eDocker containers\u003c/a\u003e. Since there is no need for customization, and we're preparing the model for production, Docker containers are a great choice for us.\u003c/p\u003e\n\u003cp\u003eDocker will create a layer between what is being deployed or served and the operating system, so it is more general, easier to scale and accommodate if there are any project changes in the future, or an expansion to other operating systems.\u003c/p\u003e\n\u003cp\u003eThis is the general context of the project. Now, let's start installing the necessary model libraries, setting up the container and learning how to serve the model!\u003c/p\u003e\n\u003ch2 id=\"importingtensorflow\"\u003eImporting Tensorflow\u003c/h2\u003e\n\u003cp\u003eIf you haven't already, let's install TensorFlow. On a Conda-based environment, you can run \u003ccode\u003econda install\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e conda install tensorflow\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eOtherwise, \u003ccode\u003epip\u003c/code\u003e makes it simple:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e pip install tensorflow\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e You can also run the installation from a Jupyter Notebook by placing an \u003cem\u003eexclamation mark\u003c/em\u003e before the command, such as: \u003ccode\u003e!conda install tensorflow\u003c/code\u003e.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eAlong with TensorFlow, let's import NumPy:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e tensorflow \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e tf\n\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e numpy \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e np\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"preprocessinganimagewithtensorflowandkeras\"\u003ePreprocessing an Image with TensorFlow and Keras\u003c/h2\u003e\n\u003cp\u003eWe'll be serving an existing, pre-trained model for general image classification, trained on ImageNet, which will allow us to focus on the \u003cem\u003eserving\u003c/em\u003e process.\u003c/p\u003e\n\u003cp\u003eLet's take an example image to classify, such as this image of swans in a lake from \u003ca href=\"https://www.pexels.com/photo/white-swan-on-body-of-water-10547480/\" rel=\"nofollow noopener\" target=\"_blank\"\u003ePexels\u003c/a\u003e (royalty free). We will use this image to understand if the model will recognize the swans, a lake, or if it will get close to that and recognize animals and nature.\u003c/p\u003e\n\u003cp\u003eOnce downloaded, let's define a path to the image to make it simple to load:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eimg_path = \u003cspan class=\"hljs-string\"\u003e\u0026#x27;tf_serving/pexels-artūras-kokorevas-10547480.jpg\u0026#x27;\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWhen feeding images into a model - we want to make sure that we follow the expected preprocessing steps. These typically include resizing and rescaling to the expected input (lest the weights can't be used), but sometimes also include normalization. All Keras models come with a \u003ccode\u003epreprocess_input()\u003c/code\u003e function that preprocesses the input for that trained model.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e EfficientNetV2's \u003ccode\u003epreprocess_input()\u003c/code\u003e function just performs \u003ccode\u003epass\u003c/code\u003e, since no preprocessing is required. However, the models do expect the inputs to be in a range of \u003ccode\u003e[0..255]\u003c/code\u003e, encoded as floats. The model itself includes a \u003ccode\u003eRescaling\u003c/code\u003e layer that'll scale them down to \u003ccode\u003e[-1, 1]\u003c/code\u003e. If you already have a \u003ccode\u003e[-1, 1]\u003c/code\u003e input, set the \u003ccode\u003einclude_preprocessing\u003c/code\u003e flag to \u003ccode\u003eFalse\u003c/code\u003e when loading the EfficientNet models.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eThe EfficientNetV2 family comes in several flavors - \u003cem\u003eB0, B1, B2, B3, S, M and L.\u003c/em\u003e B0..B3 are for comparison with the V1 of the family, which spanned B0..B7, and the models were made by adjusting the width and depth coefficients, making the models wider and deeper. S, M and L come from the V2 paper, which have a different configuration of input and output filters across the building blocks.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eYou can think of them as trading accuracy for speed, where B0 is the the \u003cem\u003elightest\u003c/em\u003e of them, while L is the largest.\u003c/p\u003e\n\u003c/blockquote\u003e\n\n \u003cdiv class=\"alert alert-reference\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-link-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eAdvice:\u003c/strong\u003e If you wish to learn more about state of the art neural network architectures, join the \u003ca href=\"/courses/convolutional-neural-networks-beyond-basic-architectures/\" target=\"_blank\"\u003e\u003cem\u003e\u0026quot;Convolutional Neural Networks - Beyond Basic Architectures\u0026quot;\u003c/em\u003e\u003c/a\u003e course!\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eDepending on your training and inference hardware, you can find a sweet spot of accuracy and speed.\u003c/p\u003e\n\u003cp\u003eThe Pexels swans image originally has a resolution 5078 by 3627 pixels, we can easily change both dimensions to 224. Typically, resizing is done \u003cem\u003eduring training\u003c/em\u003e, so efficiency in the reading and resizing operations is required. For creating optimized pipelines - \u003ccode\u003etf.io.read_file()\u003c/code\u003e is usually combined with \u003ccode\u003etf.image\u003c/code\u003e operations:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003esize = (\u003cspan class=\"hljs-number\"\u003e224\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e224\u003c/span\u003e)\n\u003cspan class=\"hljs-comment\"\u003e# Read file as bytes\u003c/span\u003e\nimg = tf.io.read_file(img_path)\n\u003cspan class=\"hljs-comment\"\u003e# Decode into PNGs\u003c/span\u003e\nimg = tf.image.decode_png(img, channels=\u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e)\n\u003cspan class=\"hljs-comment\"\u003e# Batch the input (required for vectorized operations)\u003c/span\u003e\nimg = tf.expand_dims(img, \u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e)\n\u003cspan class=\"hljs-comment\"\u003e# Perform vectorized operation to resize the images\u003c/span\u003e\nimg = tf.image.resize(img, size=size)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWhile it may seem verbose for reading a file - getting used to this syntax will play a significant role in your data and training pipelines.\u003c/p\u003e\n\u003cp\u003eLet's take a look at the image:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e matplotlib.pyplot \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e plt\n\u003cspan class=\"hljs-comment\"\u003e# Squeeze the image from a batch to a single image for Matplotlib\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# and cast to UINT8\u003c/span\u003e\nplt.imshow(tf.cast(tf.squeeze(img), dtype=tf.uint8))\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/loading-a-pretrained-tensorflow-model-into-tensorflow-serving-1.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003ch2 id=\"creatingthemodelwithtensorflow\"\u003eCreating the Model with Tensorflow\u003c/h2\u003e\n\u003cp\u003eLet's instantiate \u003ccode\u003eEfficientNetV2B0\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003emodel = tf.keras.applications.EfficientNetV2B0()\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe parameters default to the \u0026quot;ImageNet setup\u0026quot; - i.e. 'imagenet' weights are loaded in, there are 1000 output classes, and the input image size is 224 (historically most common input size). You may, of course, specify these arguments yourself, or change them to adapt to a different input pipeline:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003emodel = tf.keras.applications.EfficientNetV2B0(weights=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;imagenet\u0026#x27;\u003c/span\u003e, \n classes=\u003cspan class=\"hljs-number\"\u003e1000\u003c/span\u003e, \n input_shape=(\u003cspan class=\"hljs-number\"\u003e224\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e224\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e))\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIf you want to take a look at all the layers that the model has, you can see a list of them when executing the model's \u003ccode\u003esummary()\u003c/code\u003e method:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003emodel.summary()\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe network has ~7.14M trainable parameters:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e=========================================================\nTotal params: 7,200,312\nTrainable params: 7,139,704\nNon-trainable params: 60,608\n_________________________________________________________\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eSince we won't retrain the network in this guide, and the image is ready, we can go ahead and make predictions!\u003c/p\u003e\n\u003ch2 id=\"makingpredictions\"\u003eMaking Predictions\u003c/h2\u003e\n\u003cp\u003eTo make predictions, we can use the \u003ccode\u003epredict()\u003c/code\u003e method and store the results in a \u003ccode\u003epreds\u003c/code\u003e variable:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003epreds = model.predict(x)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAlternatively, you can simply pass the image to the model instead:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003epreds = model(x)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode\u003epreds\u003c/code\u003e here are a tensor, of \u003ccode\u003e(batch_size, class_probabilities)\u003c/code\u003e. Since we have a single image, the output tensor is of shape \u003ccode\u003e(1, 1000)\u003c/code\u003e, where there are 1000 probability scores for each class in ImageNet:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(preds)\n\u003cspan class=\"hljs-comment\"\u003e# \u0026lt;tf.Tensor: shape=(1, 1000), dtype=float32, numpy=\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# array([[5.84674963e-05, 7.39379029e-05, 7.74277505e-05, 1.28119747e-04,\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# 1.26851926e-04, 6.71151938e-05, 3.55448428e-05, 2.84188209e-05,\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# 6.39903592e-05, 2.44139865e-05, 4.29903994e-05, 5.27093216e-05,\u003c/span\u003e\n\u003cspan class=\"hljs-comment\"\u003e# ...\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eYou can get the highest probability class through the \u003ccode\u003eargmax()\u003c/code\u003e function, which returns the \u003cem\u003eindex\u003c/em\u003e of the highest value in this tensor:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003etf.argmax(preds, axis=\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e)\n\u003cspan class=\"hljs-comment\"\u003e# \u0026lt;tf.Tensor: shape=(1,), dtype=int64, numpy=array([295], dtype=int64)\u0026gt;\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe're performing \u003ccode\u003eargmax()\u003c/code\u003e on \u003ccode\u003eaxis=1\u003c/code\u003e, since we're performing it on the second axis ('column') of the tensor (we're performing \u003ccode\u003eargmax()\u003c/code\u003e across the 1000 class probabilities). So, what's the class under the index of 295? Typically, you'll have a list or dictionary of indices to classnames, either loaded in memory or in a file.\u003c/p\u003e\n\u003cp\u003eSince ImageNet has many classes, and is a common dataset/class-set to work with, TensorFlow exposes a \u003ccode\u003edecode_predictions()\u003c/code\u003e method alongside every model. By passing the predictions into it, it'll parse through the label map and return the top-5 labels associated with the top-5 most probable predictions, and their human-readable labels:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003epreds = preds.numpy()\ntf.keras.applications.efficientnet.decode_predictions(preds)\n\u003cspan class=\"hljs-string\"\u003e\u0026quot;\u0026quot;\u0026quot;\n(\u0026#x27;n09332890\u0026#x27;, \u0026#x27;lakeside\u0026#x27;, 0.2955897), \n(\u0026#x27;n09421951\u0026#x27;, \u0026#x27;sandbar\u0026#x27;, 0.24374594), \n(\u0026#x27;n01855672\u0026#x27;, \u0026#x27;goose\u0026#x27;, 0.10379495), \n(\u0026#x27;n02894605\u0026#x27;, \u0026#x27;breakwater\u0026#x27;, 0.031712674), \n(\u0026#x27;n09428293\u0026#x27;, \u0026#x27;seashore\u0026#x27;, 0.031055905)]]\n\u0026quot;\u0026quot;\u0026quot;\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn the output above, it can be seen that the network believes to be a \u003cem\u003elakeside\u003c/em\u003e in the image with the most probability, around 30% of chance, followed by a \u003cem\u003esandbar\u003c/em\u003e, a \u003cem\u003egoose\u003c/em\u003e, a \u003cem\u003ebreakwater\u003c/em\u003e and a \u003cem\u003eseashore\u003c/em\u003e. Not outstanding, but a good enough first try. Here, we need to take into consideration that the swans image is not an easy one to classify, it has tonalities that are close to each other and not very clear definitions of where the landscape ends and the frozen lake begins. Especially, in smaller resolutions, this is harder to identify.\u003c/p\u003e\n\u003ch2 id=\"savingthemodel\"\u003eSaving the Model\u003c/h2\u003e\n\u003cp\u003eThe creation and prediction simulates the iterative development cycle of a model. Let's save the \u0026quot;current version\u0026quot; of the model for deployment.\u003c/p\u003e\n\u003cp\u003eTo organize that information, let's create a folder with the name of the neural net - for instance, \u003ccode\u003eeffv2b0\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e mkdir effv2b0\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eNow, with the folder to keep track of the versions created, we need to find a way to differentiate between each version file, to name each saved model in an unique way. A common approach to naming each file uniquely is to use the time the model was saved in seconds (or the full calendar date and seconds). This number can be obtained by the \u003ccode\u003etime()\u003c/code\u003e method in Python's \u003ccode\u003etime\u003c/code\u003e library.\u003c/p\u003e\n\u003cp\u003eIn the same way we have done before, we can import time library, then obtain the current time in seconds:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e time\n\ncurrent_time = \u003cspan class=\"hljs-built_in\"\u003eint\u003c/span\u003e(time.time()) \u003cspan class=\"hljs-comment\"\u003e# int() truncates the float output, removing its decimal places\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe have generated a name for the file, let's define a path to save it inside the \u003ccode\u003eeffv2b0\u003c/code\u003e folder using Python's \u003ccode\u003ef-string\u003c/code\u003e to concatenate the folder with the number:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003epath = \u003cspan class=\"hljs-string\"\u003ef\u0026quot;effv2b0/\u003cspan class=\"hljs-subst\"\u003e{current_time}\u003c/span\u003e\u0026quot;\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eFinally, we can save the model using the \u003ccode\u003esave()\u003c/code\u003e method and passing the path as argument:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003emodel.save(path)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe final folder structure with saved model files should look like this:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e# how the folder should look like\n├── effv2b0\n│ ├── 1673311761\n│ │ ├── assets \n│ │ ├── saved_model.pb \n│ │ └── variables \n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eNotice that the \u003ccode\u003esave()\u003c/code\u003e method outputs an \u003ccode\u003eassets\u003c/code\u003e folder, a \u003ccode\u003esaved_model.pb\u003c/code\u003e file, and a \u003ccode\u003evariables\u003c/code\u003e folder. The \u003cem\u003eassets\u003c/em\u003e folder contains files used by the TensorFlow graph, the \u003cstrong\u003e.pb\u003c/strong\u003e (protobuf) file stores the model architecture and training configuration, and the \u003cem\u003evariables\u003c/em\u003e folder, the model weights. This is everything TensorFlow needs to run a trained model.\u003c/p\u003e\n\u003cp\u003eWe have already understood the main steps of preparing an image, creating a neural network model, predicting and saving a model. We can now see how this model will be served.\u003c/p\u003e\n\u003ch2 id=\"servingthemodelwithtensorflowservinganddocker\"\u003eServing the Model with Tensorflow Serving and Docker\u003c/h2\u003e\n\u003cp\u003eWith a model version selected - we can set up a Docker image to house our model and TF Serving, and deploy it.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-reference\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-link-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eAdvice:\u003c/strong\u003e If you'd like to learn more about Docker, read our \u003ca href=\"/docker-a-high-level-introduction/\" target=\"_blank\"\u003e\u003cem\u003e\u0026quot;Docker: A High Level Introduction\u0026quot;\u003c/em\u003e\u003c/a\u003e.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003ch3 id=\"installingdocker\"\u003eInstalling Docker\u003c/h3\u003e\n\u003cp\u003eThe first step to the process is installing Docker, in \u003ca href=\"https://www.docker.com/\" rel=\"nofollow noopener\" target=\"_blank\"\u003eDocker's website\u003c/a\u003e you can download the latest version according to your operating system.\u003c/p\u003e\n\u003cp\u003eAfter the download and the installation, we can test it to see if it is running. You can do this on a command line, just typing in the instruction, or inside a Jupyter Notebook, in the same way we have shown previously, by inserting an exclamation mark \u003ccode\u003e!\u003c/code\u003e before the command.\u003c/p\u003e\n\u003cp\u003eTo start Docker, type in and execute:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e open --background -a Docker\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAfter a few seconds, you should see the Docker application window opening:\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/loading-a-pretrained-tensorflow-model-into-tensorflow-serving-2.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003cp\u003eOnce Docker has started, you can then test it with:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e docker run hello-world\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis results in:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eHello from Docker!\nThis message shows that your installation appears to be working correctly.\n\nTo generate this message, Docker took the following steps:\n 1. The Docker client contacted the Docker daemon.\n 2. The Docker daemon pulled the \u0026quot;hello-world\u0026quot; image from the Docker Hub.\n (arm64v8)\n 3. The Docker daemon created a new container from that image which runs the\n executable that produces the output you are currently reading.\n 4. The Docker daemon streamed that output to the Docker client, which sent it\n to your terminal.\n\nTo try something more ambitious, you can run an Ubuntu container with:\n $ docker run -it ubuntu bash\n\nShare images, automate workflows, and more with a free Docker ID:\n https://hub.docker.com/\n\nFor more examples and ideas, visit:\n https://docs.docker.com/get-started/\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis output means we are ready to go. Docker is up and running!\u003c/p\u003e\n\u003ch3 id=\"pullingatfservingimage\"\u003ePulling a TF Serving Image\u003c/h3\u003e\n\u003cp\u003eThe next step is to have TF Serving inside Docker - which is the same as \u003cstrong\u003epulling a Tensorflow Serving image from Docker\u003c/strong\u003e, in other words, to download and load TF Serving.\u003c/p\u003e\n\u003cp\u003eTo pull the TF Serving image, execute:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e docker pull tensorflow/serving:latest-gpu\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e If you're using Mac's M1 chip, to pull the image, use:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e docker pull emacski/tensorflow-serving:latest-linux_arm64\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eAfter pulling the image, if you take a look a the Docker desktop app, in the \u003cem\u003eImages\u003c/em\u003e tab, there should be a new \u003ccode\u003etensorflow/serving\u003c/code\u003e image:\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/loading-a-pretrained-tensorflow-model-into-tensorflow-serving-3.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003cp\u003eNotice that there is also a \u003ccode\u003ehello-world\u003c/code\u003e image from the initial Docker test.\u003c/p\u003e\n\u003ch3 id=\"servingthemodel\"\u003eServing the Model\u003c/h3\u003e\n\u003cp\u003eUp to now, we have a Docker container with TF Server loaded inside of it, we can finally run it. To run the container, we will craft the following instruction:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e docker run --rm -p \u0026lt;port_number\u0026gt;:\u0026lt;port_number\u0026gt; \\\n --name \u0026lt;container_name\u0026gt; \\\n -v \u003cspan class=\"hljs-string\"\u003e\u0026quot;\u0026lt;local_path_to_net_folder\u0026gt;:\u0026lt;internal_tfserving_path_/models/+net_folder\u0026gt;\u0026quot;\u003c/span\u003e \\\n -e MODEL_NAME=\u0026lt;same_as_net_folder\u0026gt; \\\n \u0026lt;name_of_pulled_image\u0026gt;\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn the above instruction, there are 5 Docker flags, \u003ccode\u003e--rm\u003c/code\u003e, \u003ccode\u003e-p\u003c/code\u003e, \u003ccode\u003e--name\u003c/code\u003e, \u003ccode\u003e-v\u003c/code\u003e, \u003ccode\u003e-e\u003c/code\u003e. This is what each one means:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e--rm\u003c/code\u003e: same as remove, it tells Docker to clean up the container after it exits;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-p\u003c/code\u003e: short for port, it tells Docker in which port the container runs;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e--name\u003c/code\u003e: specifies what is the name of the container;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-v\u003c/code\u003e: short for volume, when used with colon marks \u003ccode\u003e:\u003c/code\u003e makes the first path, or \u003cem\u003ehost\u003c/em\u003e path available to exchange information with the second path, or the path inside the container. In our example, this means we are transferring or copying what is in our folder to TF Serving's \u003ccode\u003e/models/\u003c/code\u003e folder and enabling changes in it;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-e\u003c/code\u003e: same as env or environment variables, in our example it defines a MODEL_NAME variable that will exist inside the container.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eAlso, in the above command, the text inside \u003ccode\u003e\u0026lt;\u003c/code\u003e \u003ccode\u003e\u0026gt;\u003c/code\u003e is to be substituted by the ports by which the model will be available, the name of the container, the local path to the network folder, followed by the corresponding path in TF Serving to the network folder, which is inside a \u003ccode\u003e/models/\u003c/code\u003e folder, the model name, and the name of the Docker image. Bellow is an example:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e docker run --rm -p 8501:8501 \\\n --name tfserving_effv2 \\\n -v \u003cspan class=\"hljs-string\"\u003e\u0026quot;/Users/csamp/Documents/stack_ab/effv2b0:/models/effv2b0\u0026quot;\u003c/span\u003e \\\n -e MODEL_NAME=effv2b0 \\\n tensorflow/serving:latest-gpu\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e if you are using Mac's M1 chip, the only difference in the command is in the last line, which will have the name of the \u003ccode\u003eemacski/tensorflow-serving:latest-linux_arm64\u003c/code\u003e image:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e docker run --rm -p 8501:8501 \\\n --name tfserving_effv2 \\\n -v \u003cspan class=\"hljs-string\"\u003e\u0026quot;/Users/csamp/Documents/stack_ab/effv2b0:/models/effv2b0\u0026quot;\u003c/span\u003e \\\n -e MODEL_NAME=effv2b0 \\\n emacski/tensorflow-serving:latest-linux_arm64\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIf you also end up using another image for your system, you only need to change the last line.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eAfter executing command, you will see a long output ending in \u003cstrong\u003e\u0026quot;Entering the event loop ...\u0026quot;\u003c/strong\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e2023-01-17 10:01:33.219123: I external/tf_serving/tensorflow_serving/model_servers/server.cc:89] Building single TensorFlow model file config: model_name: effv2b0 model_base_path: /models/effv2b0\n2023-01-17 10:01:33.220437: I external/tf_serving/tensorflow_serving/model_servers/server_core.cc:465] Adding/updating models.\n2023-01-17 10:01:33.220455: I external/tf_serving/tensorflow_serving/model_servers/server_core.cc:591] (Re-)adding model: effv2b0\n2023-01-17 10:01:33.330517: I external/tf_serving/tensorflow_serving/core/basic_manager.cc:740] Successfully reserved resources to load servable {name: effv2b0 version: 1670550215}\n2023-01-17 10:01:33.330545: I external/tf_serving/tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: effv2b0 version: 1670550215}\n2023-01-17 10:01:33.330554: I external/tf_serving/tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: effv2b0 version: 1670550215}\n2023-01-17 10:01:33.331164: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:38] Reading SavedModel from: /models/effv2b0/1670550215\n2023-01-17 10:01:33.465487: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:90] Reading meta graph with tags { serve }\n2023-01-17 10:01:33.465524: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:132] Reading SavedModel debug info (if present) from: /models/effv2b0/1670550215\n2023-01-17 10:01:33.468611: I external/org_tensorflow/tensorflow/core/common_runtime/process_util.cc:146] Creating new thread pool with default inter op setting: 2. Tune using inter_op_parallelism_threads for best performance.\n2023-01-17 10:01:33.763910: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:211] Restoring SavedModel bundle.\n2023-01-17 10:01:33.781220: W external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:87] Failed to get CPU frequency: -1\n2023-01-17 10:01:34.390394: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:195] Running initialization op on SavedModel bundle at path: /models/effv2b0/1670550215\n2023-01-17 10:01:34.516968: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:283] SavedModel load for tags { serve }; Status: success: OK. Took 1185801 microseconds.\n2023-01-17 10:01:34.536880: I external/tf_serving/tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/effv2b0/1670550215/assets.extra/tf_serving_warmup_requests\n2023-01-17 10:01:34.539248: I external/tf_serving/tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: effv2b0 version: 1670550215}\n2023-01-17 10:01:34.540738: I external/tf_serving/tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models\n2023-01-17 10:01:34.540785: I external/tf_serving/tensorflow_serving/model_servers/server.cc:133] Using InsecureServerCredentials\n2023-01-17 10:01:34.540794: I external/tf_serving/tensorflow_serving/model_servers/server.cc:383] Profiler service is enabled\n2023-01-17 10:01:34.542004: I external/tf_serving/tensorflow_serving/model_servers/server.cc:409] Running gRPC ModelServer at 0.0.0.0:8500 ...\n[warn] getaddrinfo: address family for nodename not supported\n2023-01-17 10:01:34.543973: I external/tf_serving/tensorflow_serving/model_servers/server.cc:430] Exporting HTTP/REST API at:localhost:8501 ...\n[evhttp_server.cc : 245] NET_LOG: Entering the event loop ...\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis means that the TF model is being served!\u003c/p\u003e\n\u003cp\u003eYou can also look in the Docker desktop, in the \u003cem\u003eContainers\u003c/em\u003e tab, you will see a line with the container name we have specified in the instructions’ \u003ccode\u003e--name\u003c/code\u003e tag, in this case, \u003ccode\u003etfserving_effv2\u003c/code\u003e, followed by the image link, the status as \u003cem\u003erunning\u003c/em\u003e and the ports:\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/loading-a-pretrained-tensorflow-model-into-tensorflow-serving-4.png\" alt=\"\"\u003e\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e If you want to run everything inside a Jupyter Notebook, in this step, you can interrupt the kernel after executing the serving command and reading the \u0026quot;Entering the event loop ...\u0026quot; message. This will only stop the cell, but Docker will continue running and you can proceed to execute your next cell.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003ch3 id=\"sendingrequestsandgettingaresponsefromthemodel\"\u003eSending Requests and Getting a Response from the Model\u003c/h3\u003e\n\u003cp\u003eOur model is already accessible through TF Serving in the 8501 port. To be able to access it through the web, we need to send data, or make a \u003cstrong\u003erequest\u003c/strong\u003e to the served model, and then receive data as a \u003cstrong\u003eresponse\u003c/strong\u003e, getting our predictions, and this is usually done over HTTP. This is how the web works and communicates. To be able to use requests and responses, we will import Python's \u003ccode\u003erequests\u003c/code\u003e library.\u003c/p\u003e\n\u003cp\u003eTypically, when sending messages over HTTP, we send JSON-formatted messages, as they're both lightweight and very human-readable, and conform to the most widely used language on the web - JavaScript. Since we'll also be sending a JSON payload, we'll import Python's \u003ccode\u003ejson\u003c/code\u003e library:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e json\n\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e requests\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAfter importing the libraries, we need to define the location we want to access - same address of where our model is being served - called an \u003cstrong\u003eendpoint\u003c/strong\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eendpoint = \u003cspan class=\"hljs-string\"\u003e\u0026#x27;http://localhost:8501/v1/models/effv2b0:predict\u0026#x27;\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe're serving the model on our local machine, hence the \u003ccode\u003elocalhost\u003c/code\u003e, though the same steps are taken for a remote virtual machine as well. The \u003ccode\u003ev1\u003c/code\u003e version is automatically created and tracked by TF Server, and we are accessing the \u003ccode\u003epredict\u003c/code\u003e method of the \u003ccode\u003eeffv2b0\u003c/code\u003e model.\u003c/p\u003e\n\u003cp\u003eLet's set the header's content-type for the HTTP request:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eheader = {\u003cspan class=\"hljs-string\"\u003e\u0026quot;content-type\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;application/json\u0026quot;\u003c/span\u003e} \n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe last thing we need to do is to send the data for the model to predict, which would be our preprocessed swan image, that we will rearrange into a json format with the \u003ccode\u003ejson.dumps()\u003c/code\u003e method. The resulting JSON:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003ebatch_json = json.dumps({\u003cspan class=\"hljs-string\"\u003e\u0026quot;instances\u0026quot;\u003c/span\u003e: x.tolist()}) \u003cspan class=\"hljs-comment\"\u003e# tolist() transforms x array into a list of arrays so json can understand it\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eTensorflow will be expecting a json with the \u003ccode\u003einstances\u003c/code\u003e key, so it is mandatory to name the field \u003cem\u003einstances\u003c/em\u003e.\u003c/p\u003e\n\u003cp\u003eSo far, we have an endpoint, a header and a JSON string with one image. It is time to tie it all together in a web request. To do this, we will use the \u003ccode\u003erequests.post()\u003c/code\u003e method that receives a URL, data, headers and returns a response:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003ejson_res = requests.post(url=endpoint, \n data=batch_json, \n headers=header)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAfter receiving this json, we can access its content by loading it with \u003ccode\u003ejson.loads()\u003c/code\u003e and accessing its text with \u003ccode\u003ejson_res.text\u003c/code\u003e. The returned response is in a dictionary format:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eserver_preds = json.loads(json_res.text)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe can then pass this server predictions dictionary to the same \u003ccode\u003edecode_predictions()\u003c/code\u003e method we have used previously. There are only two adaptations to be made - the first is to access the \u003ccode\u003epredictions\u003c/code\u003e key inside the dict, and then to transform the predictions list into an array:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Predicted:\u0026#x27;\u003c/span\u003e, decode_predictions(np.array(server_preds[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;predictions\u0026#x27;\u003c/span\u003e])))\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis results in:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003ePredicted: [[\n(\u0026#x27;n09332890\u0026#x27;, \u0026#x27;lakeside\u0026#x27;, 0.295589358), \n(\u0026#x27;n09421951\u0026#x27;, \u0026#x27;sandbar\u0026#x27;, 0.243745327), \n(\u0026#x27;n01855672\u0026#x27;, \u0026#x27;goose\u0026#x27;, 0.10379523), \n(\u0026#x27;n02894605\u0026#x27;, \u0026#x27;breakwater\u0026#x27;, 0.0317126848), \n(\u0026#x27;n09428293\u0026#x27;, \u0026#x27;seashore\u0026#x27;, 0.0310558397)]]\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eHere, we have the same predictions we made in our machine now being served and accessed through the web. Mission accomplished!\u003c/p\u003e\n\u003cp\u003eThe final code to access the served model is the following:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e json\n\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e requests\n\nendpoint = \u003cspan class=\"hljs-string\"\u003e\u0026#x27;http://localhost:8501/v1/models/effv2b0:predict\u0026#x27;\u003c/span\u003e\nheader = {\u003cspan class=\"hljs-string\"\u003e\u0026quot;content-type\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;application/json\u0026quot;\u003c/span\u003e} \nbatch_json = json.dumps({\u003cspan class=\"hljs-string\"\u003e\u0026quot;instances\u0026quot;\u003c/span\u003e: x.tolist()})\n\njson_res = requests.post(url=endpoint, data=batch_json, headers=header)\nserver_preds = json.loads(json_res.text)\n\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Predicted:\u0026#x27;\u003c/span\u003e, decode_predictions(np.array(server_preds[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;predictions\u0026#x27;\u003c/span\u003e])))\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eIn this guide, we have learned what a TensorFlow pre-trained model is, how to use it and in which context to use it. We have also learned about serving this model with Docker, and why using Docker would be a good idea according to our objectives.\u003c/p\u003e\n\u003cp\u003eBesides following all the steps to image transformation, model creation, prediction, mode saving, model serving and web requesting, we have also seen how little effort is involved in using another model in this structure.\u003c/p\u003e\n","parent_id":null,"type":"article","visibility":"public","img_feature":null,"is_featured":false,"locale":"en","custom_excerpt":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"comment_id":null,"og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":"In this guide, learn how to prepare, dockerize and deploy a TensorFlow Model using TensorFlow Serving, as well as how to send POST requests for inference in Python.","read_time_min":28,"published_at":1677850440000,"created_at":1668988977435,"updated_at":1682510030465,"tags":[{"id":9,"name":"python","slug":"python","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431358631000,"updated_at":1431358631000,"_pivot_content_id":1694,"_pivot_tag_id":9,"_pivot_sort_order":0},{"id":57,"name":"artificial intelligence","slug":"artificial-intelligence","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1442517465000,"updated_at":1442517465000,"_pivot_content_id":1694,"_pivot_tag_id":57,"_pivot_sort_order":6},{"id":75,"name":"machine learning","slug":"machine-learning","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1507305534000,"updated_at":1507305534000,"_pivot_content_id":1694,"_pivot_tag_id":75,"_pivot_sort_order":4},{"id":78,"name":"tensorflow","slug":"tensorflow","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1508009047000,"updated_at":1508009047000,"_pivot_content_id":1694,"_pivot_tag_id":78,"_pivot_sort_order":1},{"id":106,"name":"data science","slug":"data-science","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1536865458000,"updated_at":1536865458000,"_pivot_content_id":1694,"_pivot_tag_id":106,"_pivot_sort_order":3},{"id":115,"name":"computer vision","slug":"computer-vision","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1545946018000,"updated_at":1545946018000,"_pivot_content_id":1694,"_pivot_tag_id":115,"_pivot_sort_order":2},{"id":181,"name":"deep learning","slug":"deep-learning","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1595356360000,"updated_at":1595356360000,"_pivot_content_id":1694,"_pivot_tag_id":181,"_pivot_sort_order":5}],"contributors":[{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","_pivot_content_id":1694,"_pivot_user_id":16,"_pivot_role":"editor","_pivot_sort_order":1},{"id":575,"name":"Cássia Sampaio","slug":"cassia","role_id":null,"img_profile":"https://s3.stackabuse.com/media/users/60316bfa4cd83016fae6d119ec3daac4.jpeg","img_cover":null,"bio_html":"\u003cp\u003eData Scientist, Research Software Engineer, and teacher. Cassia is passionate about transformative processes in data, technology and life. She is graduated in Philosophy and Information Systems, with a Strictu Sensu Master's Degree in the field of Foundations Of Mathematics.\u003c/p\u003e\n","website":null,"location":"São Paulo, Brazil","facebook":null,"twitter":"cassiasamp","github":"cassiasamp","created_at":1654707399738,"updated_at":1697580332208,"role":"author","_pivot_content_id":1694,"_pivot_user_id":575,"_pivot_role":"author","_pivot_sort_order":0}],"_pivot_user_id":16,"_pivot_content_id":1694},{"id":1762,"title":"Training Neural Radiance Field (NeRF) Models with Keras/TensorFlow and DeepVision","slug":"training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision","body_html":"\u003cp\u003eNeural Radiance Fields, colloquially known as \u003cem\u003eNeRFs\u003c/em\u003e have struck the world by storm in 2020, released alongside the paper \u003ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https://arxiv.org/abs/2003.08934\"\u003e\u003cem\u003e\u0026quot;NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis\u0026quot;\u003c/em\u003e\u003c/a\u003e, and are still the cornerstone of high quality synthesis of novel views, given sparse images and camera positions.\u003c/p\u003e\n\u003cp\u003eSince then, they've found numerous applications, but probably most prominently in geospatial volumetric modeling, with companies like Google relying on NeRFs to create 3D structures of buildings and heritage sites from various angles of sattelite imagery, and companies specializing in performing 3D reconstruction and digitization of well known cultural sites.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIn this guide, we'll be training a Neural Radiance Field (NeRF) model on the original Tiny NeRF dataset, using TensorFlow/Keras and DeepVision, to perform novel view synthesis/3D reconstruction.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eIn a single hour, on a commercial machine, you'll render novel views of images from the TinyNeRF dataset:\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision-1.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003ch2 id=\"novelviewsynthesisandneuralradiancefields\"\u003eNovel View Synthesis and Neural Radiance Fields\u003c/h2\u003e\n\u003cp\u003eThis section provides a simplified summary/introduction to the way Neural Radiance Fields work, but it may take some time to truly intuitively digest how they work if you're new to the field.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-reference\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-link-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e The original paper as well as educational video and graphics associated with it are great learning materials. If you're interested in understand the underlying concept of \u003cem\u003eradiance fields\u003c/em\u003e that NeRFs rely on to represent a scene, the \u003ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/Light_field\"\u003e\u003cem\u003eWikipedia entry for \u0026quot;light fields\u0026quot;\u003c/em\u003e\u003c/a\u003e provides a great introduction, but they can be summarized in a high-level fashion as\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u0026quot;The light field is a vector function that describes the amount of light flowing in every direction through every point in space\u0026quot;.\u003c/p\u003e\n\u003c/blockquote\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eNeRFs are used for \u003cem\u003enovel view synthesis\u003c/em\u003e - creating new views of objects and images, given some views. In effect, you can think of novel view synthesis as 2D-\u0026gt;3D conversion, and many approaches to solve this problem exist, some more successful than others.\u003c/p\u003e\n\u003cp\u003eHistorically a challenging problem, the solution proposed by NeRFs is exceedingly simple yet yields state of the art results, generating very high quality images from novel angles:\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision-2.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003cp\u003eThis, naturally, positioned them as a foundational approach to solving novel view synthesis, with many subsequent papers exploring, adjusting and improving on the ideas present therein.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-reference\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-link-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eAdvice:\u003c/strong\u003e The \u003ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https://www.matthewtancik.com/nerf\"\u003ewebsite\u003c/a\u003e released alongside the paper contains an amazing showcase of the method and its results, and \u003ca target=\"_blank\" rel=\"nofollow noopener noreferrer\" href=\"https://www.youtube.com/watch?v=JuH79E8rdKc\u0026ab_channel=MatthewTancik\"\u003ean educational video\u003c/a\u003e that builds a good intuition for how these networks work has been released officially.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eThe pipeline from data to results can be summarized as:\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision-3.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003cp\u003eWhere the neural network learns from sparse images with synthetically generated \u003cem\u003erays\u003c/em\u003e that are projected and sampled at regular intervals. The images are positioned in space given the metadata about the images, such as the camera positions when the images were taken. Because of this - you can't just input any images, and \u003cem\u003erequire\u003c/em\u003e camera positions to be able to accurately position the images in space for the rays to create a comprehendable set of points. The sampled points then form a 3D set of points that represent the volumetric scene:\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision-4.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003cp\u003eThe neural network approximates a \u003cem\u003evolumetric scene function\u003c/em\u003e - the RGB values and density (σ) of a scene. In effect, we train the network to \u003cem\u003ememorize\u003c/em\u003e the color and density of each input point, in order to be able to reconstruct the images from novel view points. That being said - NeRFs aren't trained on a set of images and can extrapolate to new ones. NeRFs are trained to encode a scene, and are then only used for that one scene, \u003cem\u003eas the weights of the network itself represent the scene.\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003eThis is the main \u0026quot;drawback\u0026quot; of NeRFs - you have to train a network for each scene you want to encode, and the training process is both somewhat slow and requires lots of memory for large inputs. Improvements in training time are an area of research, with novel techniques such as \u003ca href=\"https://sunset1995.github.io/dvgo/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"\u003e\u003cem\u003e\u0026quot;Direct Voxel Grid Optimization\u0026quot;\u003c/em\u003e\u003c/a\u003e that significantly improve training time without trading off image quality in the process.\u003c/p\u003e\n\u003ch2 id=\"neuralradiancefieldsindeepvisionandtensorflow\"\u003eNeural Radiance Fields in DeepVision and TensorFlow\u003c/h2\u003e\n\u003cp\u003eNeRF implementations can be a bit daunting for those new to volumetric rendering, and the code repositories typically include many helper methods for dealing with volumetric data, which may look unintuitive to some. DeepVision is a novel computer vision library that aims to unify computer vision under a common API, with interchangeable backends (TensorFlow and PyTorch), automatic weight conversions between models, and models with identical implementations across backend frameworks.\u003c/p\u003e\n\u003cp\u003eTo lower the barrier to entry, \u003ca target=\"_blank\" href=\"https://github.com/DavidLandup0/deepvision\" rel=\"nofollow noopener noreferrer\"\u003eDeepVision\u003c/a\u003e offers a simple yet true-to-the-original implementation of Neural Radiance Field models, with multiple setups to accomodate more and less powerful machines with varying hardware setups:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eNeRFTiny\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eNeRFSmall\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eNeRFMedium\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eNeRF\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eNeRFLarge\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eTwo parameters are used to create these setups - \u003ccode\u003ewidth\u003c/code\u003e and \u003ccode\u003edepth\u003c/code\u003e. Since NeRFs are, in essence, just an MLP model consisting of \u003ccode\u003etf.keras.layers.Dense()\u003c/code\u003e layers (with a single concatenation between layers), the \u003ccode\u003edepth\u003c/code\u003e directly represents the number of \u003ccode\u003eDense\u003c/code\u003e layers, while \u003ccode\u003ewidth\u003c/code\u003e represents the number of units used in each one.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eNeRF\u003c/code\u003e corresponds to the setup used in the original paper, but it may be difficult to run on some local machines, in which case, \u003ccode\u003eNeRFMedium\u003c/code\u003e provides very similar performance with smaller memory requirements.\u003c/p\u003e\n\u003cp\u003eLet's go ahead and install DeepVision with \u003ccode\u003epip\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e$\u003c/span\u003e\u003cspan class=\"bash\"\u003e pip install deepvision-toolkit\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eInstantiating a model is as easy as:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e deepvision\nmodel = deepvision.models.NeRFMedium(input_shape=(num_pos, input_features), \n backend=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;tensorflow\u0026#x27;\u003c/span\u003e) \nmodel.summary()\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe model itself is exceedingly simple:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eModel: \u0026quot;ne_rftf\u0026quot;\n__________________________________________________________________________________________________\n Layer (type) Output Shape Param # Connected to \n==================================================================================================\n input_1 (InputLayer) [(None, 640000, 195 0 [] \n )] \n \n dense (Dense) (None, 640000, 128) 25088 [\u0026#x27;input_1[0][0]\u0026#x27;] \n \n dense_1 (Dense) (None, 640000, 128) 16512 [\u0026#x27;dense[0][0]\u0026#x27;] \n \n dense_2 (Dense) (None, 640000, 128) 16512 [\u0026#x27;dense_1[0][0]\u0026#x27;] \n \n dense_3 (Dense) (None, 640000, 128) 16512 [\u0026#x27;dense_2[0][0]\u0026#x27;] \n \n dense_4 (Dense) (None, 640000, 128) 16512 [\u0026#x27;dense_3[0][0]\u0026#x27;] \n \n concatenate (Concatenate) (None, 640000, 323) 0 [\u0026#x27;dense_4[0][0]\u0026#x27;, \n \u0026#x27;input_1[0][0]\u0026#x27;] \n \n dense_5 (Dense) (None, 640000, 128) 41472 [\u0026#x27;concatenate[0][0]\u0026#x27;] \n \n dense_6 (Dense) (None, 640000, 4) 516 [\u0026#x27;dense_5[0][0]\u0026#x27;] \n \n==================================================================================================\nTotal params: 133,128\nTrainable params: 133,124\nNon-trainable params: 4\n__________________________________________________________________________________________________\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWe'll take a closer look at how to deal with the outputs of the model and how to render the images produced by the weights of the model, in a moment.\u003c/p\u003e\n\u003ch2 id=\"loadingthetinynerfdataset\"\u003eLoading the TinyNeRF Dataset\u003c/h2\u003e\n\u003cp\u003eSince NeRFs can be somewhat expensive to train on larger input images, they were released with a small dataset of 100x100 images, dubbed \u003cem\u003eTinyNeRF\u003c/em\u003e to make testing and iterations easier. It has subsequently become a classic dataset to try out NeRFs on and for entering the field, similar to how MNIST became the \u0026quot;Hello World\u0026quot; of digit recognition.\u003c/p\u003e\n\u003cp\u003eThe dataset is available as an \u003ccode\u003e.npz\u003c/code\u003e file, and contains images, focal points (used for normalization) and camera poses, and can be obtained from the official code release:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e requests\n\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e numpy \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e np\n\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e matplotlib.pyplot \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e plt\n\nurl = \u003cspan class=\"hljs-string\"\u003e\u0026quot;https://people.eecs.berkeley.edu/~bmild/nerf/tiny_nerf_data.npz\u0026quot;\u003c/span\u003e\nsave_path = \u003cspan class=\"hljs-string\"\u003e\u0026#x27;tiny_nerf.npz\u0026#x27;\u003c/span\u003e\n\nfile_data = requests.get(url).content\n\u003cspan class=\"hljs-keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"hljs-built_in\"\u003eopen\u003c/span\u003e(save_path, \u003cspan class=\"hljs-string\"\u003e\u0026quot;wb\u0026quot;\u003c/span\u003e) \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e file:\n file.write(file_data)\n\ndata = np.load(save_path)\n\nimages, poses, focal = data[\u003cspan class=\"hljs-string\"\u003e\u0026quot;images\u0026quot;\u003c/span\u003e], data[\u003cspan class=\"hljs-string\"\u003e\u0026quot;poses\u0026quot;\u003c/span\u003e], data[\u003cspan class=\"hljs-string\"\u003e\u0026quot;focal\u0026quot;\u003c/span\u003e]\n\n\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(images.shape) \u003cspan class=\"hljs-comment\"\u003e# (106, 100, 100, 3)\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(poses.shape) \u003cspan class=\"hljs-comment\"\u003e# (106, 4, 4)\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(focal) \u003cspan class=\"hljs-comment\"\u003e# array(138.8888789)\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThere are 106 images, 100x100 each, with 3 channels (RGB). All of the images are of a small lego bulldozer. Let's plot the first five images:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003efig, ax = plt.subplots(\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e, figsize=(\u003cspan class=\"hljs-number\"\u003e20\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e12\u003c/span\u003e))\n\u003cspan class=\"hljs-keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"hljs-keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e):\n ax[i].imshow(images[i])\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision-5.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003cem\u003ecamera positions\u003c/em\u003e supplied in the dataset are crucial for being able to reconstruct the space in which the images were taken, which allows us to project rays through the images and form a volumetric space with the sampled points on each projection.\u003c/p\u003e\n\u003cp\u003eHowever, since this dataset requires lots of preparation for the training phase - DeepVision offers a \u003ccode\u003eload_tiny_nerf()\u003c/code\u003e dataset loader, that'll perform the preparation for you, with an optional \u003ccode\u003evalidation_split\u003c/code\u003e, \u003ccode\u003epos_embed\u003c/code\u003e and \u003ccode\u003enum_ray_samples\u003c/code\u003e, and returns a vanilla \u003ccode\u003etf.data.Dataset\u003c/code\u003e that you can create high-performance pipelines with:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e deepvision\n\ntrain_ds, valid_ds = deepvision.datasets.load_tiny_nerf(pos_embed=\u003cspan class=\"hljs-number\"\u003e16\u003c/span\u003e,\n num_ray_samples=\u003cspan class=\"hljs-number\"\u003e32\u003c/span\u003e,\n save_path=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;tiny_nerf.npz\u0026#x27;\u003c/span\u003e,\n validation_split=\u003cspan class=\"hljs-number\"\u003e0.2\u003c/span\u003e,\n backend=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;tensorflow\u0026#x27;\u003c/span\u003e) \n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eYou absolutely don't need to create a validation set here, since the point \u003cem\u003eis\u003c/em\u003e to fully overfit and memorize the images, and the validation set here is created primarily as a sanity check.\u003c/p\u003e\n\u003cp\u003eLet's take a look at the length and input shapes in the training dataset:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\"\u003e\u0026#x27;Train dataset length:\u0026#x27;\u003c/span\u003e, \u003cspan class=\"hljs-built_in\"\u003elen\u003c/span\u003e(train_ds))\n\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(train_ds)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis results in:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eTrain dataset length: 84\n\u0026lt;ZipDataset element_spec=(TensorSpec(shape=(100, 100, 3), dtype=tf.float32, name=None), \n (TensorSpec(shape=(320000, 99), dtype=tf.float32, name=None), TensorSpec(shape=(100, 100, 32), dtype=tf.float32, name=None)))\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode\u003epos_embed\u003c/code\u003e argument sets the number of \u003cem\u003epositional embeddings\u003c/em\u003e used to transform the 5D coordinates (x, y, z and viewing angles Theta and Phi). The positional embeddings were \u003cem\u003ecrucial\u003c/em\u003e for the network to be able to represent higher frequency functions, which was a \u0026quot;missing ingridient\u0026quot; in making this sort of technique work in the past, since networks struggled to approximate functions representing high-frequency variation in color and geometry, due to their bias towards learning low-frequency functions instead:\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision-6.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003enum_ray_samples\u003c/code\u003e represents the number of samples taken along the length of each ray projected in the image.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eNaturally, the more positional embeddings and ray samples you use, the higher the resolution of the volumetric scene you're approximating, and thus, the more detailed the final images will be, at the cost of higher computational costs.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"traininganerfwithtensorflowkerasanddeepvision\"\u003eTraining a NeRF with TensorFlow/Keras and DeepVision\u003c/h2\u003e\n\u003cp\u003eLet's take a look at an end-to-end example of loading the data, preparing the dataset, instantiating a model and training it using DeepVision and the TensorFlow/Keras ecosystem:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e deepvision\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e deepvision.datasets \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e load_tiny_nerf\n\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e tensorflow \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e tf\n\nconfig = {\n \u003cspan class=\"hljs-string\"\u003e\u0026#x27;img_height\u0026#x27;\u003c/span\u003e: \u003cspan class=\"hljs-number\"\u003e100\u003c/span\u003e,\n \u003cspan class=\"hljs-string\"\u003e\u0026#x27;img_width\u0026#x27;\u003c/span\u003e: \u003cspan class=\"hljs-number\"\u003e100\u003c/span\u003e,\n \u003cspan class=\"hljs-string\"\u003e\u0026#x27;pos_embed\u0026#x27;\u003c/span\u003e: \u003cspan class=\"hljs-number\"\u003e32\u003c/span\u003e,\n \u003cspan class=\"hljs-string\"\u003e\u0026#x27;num_ray_samples\u0026#x27;\u003c/span\u003e: \u003cspan class=\"hljs-number\"\u003e64\u003c/span\u003e,\n \u003cspan class=\"hljs-string\"\u003e\u0026#x27;batch_size\u0026#x27;\u003c/span\u003e: \u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e\n}\n\nnum_pos = config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;img_height\u0026#x27;\u003c/span\u003e] * config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;img_width\u0026#x27;\u003c/span\u003e] * config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;num_ray_samples\u0026#x27;\u003c/span\u003e]\ninput_features = \u003cspan class=\"hljs-number\"\u003e6\u003c/span\u003e * config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;pos_embed\u0026#x27;\u003c/span\u003e] + \u003cspan class=\"hljs-number\"\u003e3\u003c/span\u003e\n\ntrain_ds, valid_ds = load_tiny_nerf(pos_embed=config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;pos_embed\u0026#x27;\u003c/span\u003e],\n num_ray_samples=config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;num_ray_samples\u0026#x27;\u003c/span\u003e],\n save_path=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;tiny_nerf.npz\u0026#x27;\u003c/span\u003e,\n validation_split=\u003cspan class=\"hljs-number\"\u003e0.2\u003c/span\u003e,\n backend=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;tensorflow\u0026#x27;\u003c/span\u003e) \n\ntrain_ds = train_ds.batch(config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;batch_size\u0026#x27;\u003c/span\u003e]).prefetch(tf.data.AUTOTUNE)\nvalid_ds = valid_ds.batch(config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;batch_size\u0026#x27;\u003c/span\u003e]).prefetch(tf.data.AUTOTUNE)\n\nmodel = deepvision.models.NeRFMedium(input_shape=(num_pos, input_features),\n backend=\u003cspan class=\"hljs-string\"\u003e\u0026#x27;tensorflow\u0026#x27;\u003c/span\u003e)\n\nmodel.\u003cspan class=\"hljs-built_in\"\u003ecompile\u003c/span\u003e(optimizer=tf.keras.optimizers.Adam(learning_rate=\u003cspan class=\"hljs-number\"\u003e1e-3\u003c/span\u003e), \n loss=tf.keras.losses.MeanSquaredError())\n \ncallbacks = [tf.keras.callbacks.ReduceLROnPlateau()]\n\nhistory = model.fit(train_ds, \n epochs=\u003cspan class=\"hljs-number\"\u003e50\u003c/span\u003e, \n validation_data=valid_ds, \n callbacks=callbacks)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eOn an Nvidia GTX1660Super, training with 32 positional embeddings and 64 ray samples takes ~1min per epoch, but smaller setups, such as 8-16 positional embeddings and 32 ray samples may take as little as ~7s per epoch:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eEpoch 1/50\n84/84 [==============================] - 65s 746ms/step - loss: 0.0603 - psnr: 12.6432 - val_loss: 0.0455 - val_psnr: 13.7601 - lr: 0.0010\n...\nEpoch 50/50\n84/84 [==============================] - 55s 658ms/step - loss: 0.0039 - psnr: 24.1984 - val_loss: 0.0043 - val_psnr: 23.8576 - lr: 0.0010\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAfter roughly a single hour, on a single commercial GPU, the model achieves ~24 PSNR. The thing with NeRFs is - the longer you train, the closer it'll get to representations of the original images, meaning, you'll typically see the metrics increasing through time as you train more. It does help to have a \u003ccode\u003eReduceLROnPlateau\u003c/code\u003e callback to handle learning rate reduction to fine tune the results nearing the end of training.\u003c/p\u003e\n\u003cp\u003eThe model reports two metrics - \u003ccode\u003eloss\u003c/code\u003e and \u003ccode\u003epsnr\u003c/code\u003e. The loss is the mean squared error for each pixel, and works as a great loss function for NeRFs, but is difficult to interpret.\u003c/p\u003e\n\u003cp\u003e\u003cem\u003ePeak Signal-to-Noise Ratio (PSNR)\u003c/em\u003e is the ratio between the signal (maximum power of a signal) and the noise (power of the noise that corrupts the fidelity of the signal) which degrades the image. Peak Signal-to-Noise Ratio can be used as an \u003cem\u003eimage quality\u003c/em\u003e metric, and is very intuitive to interpret for humans.\u003c/p\u003e\n\u003cp\u003eAlready at a PSNR of 24, images become fairly clear, and NeRFs can reach PSNRs of over 40 on TinyNeRF given enough training time.\u003c/p\u003e\n\u003ch2 id=\"visualizingoutputs\"\u003eVisualizing Outputs\u003c/h2\u003e\n\u003cp\u003eThe network outputs a tensor of shape \u003ccode\u003e[batch_size, 640000, 4]\u003c/code\u003e where the channels represent RGB and density, and the 640000 points encode the scene. To represent these as images, we'll want to reshape the tensor to a shape of \u003ccode\u003e(batch_size, img_height, img_width, num_ray_samples, 4)\u003c/code\u003e, and then disect the 4 channels into RGB and sigma and process them into an image (and optionally, a depth/accuracy map).\u003c/p\u003e\n\u003cp\u003eSpecifically, the RGB channels are passed through a \u003cem\u003esigmoid\u003c/em\u003e activation, while the sigma channel is passed through a \u003cem\u003eReLU\u003c/em\u003e activation, before being processed further and reduced to a tensor of shape \u003ccode\u003e(batch_size, img_height, img_width, rgb_channels)\u003c/code\u003e, and two tensors of shape \u003ccode\u003e(batch_size, img_height, img_width, depth_channel)\u003c/code\u003e and \u003ccode\u003e(batch_size, img_height, img_width, accuracy)\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eTo make this process easier, we can use the \u003ccode\u003enerf_render_image_and_depth_tf()\u003c/code\u003e function from \u003ccode\u003evolumetric_utils\u003c/code\u003e, which accepts the model to predict RGB and sigma from inputs, and returns a batch of images, depth maps and accuracy maps:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e matplotlib.pyplot \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e plt\n\u003cspan class=\"hljs-keyword\"\u003efrom\u003c/span\u003e deepvision.models.volumetric.volumetric_utils \u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e nerf_render_image_and_depth_tf\n\n\u003cspan class=\"hljs-keyword\"\u003efor\u003c/span\u003e batch \u003cspan class=\"hljs-keyword\"\u003ein\u003c/span\u003e train_ds.take(\u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e):\n (images, rays) = batch\n (rays_flat, t_vals) = rays\n \n image_batch, depth_maps, _ = nerf_render_image_and_depth_tf(model=model, \n rays_flat=rays_flat, \n t_vals=t_vals,\n img_height=config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;img_height\u0026#x27;\u003c/span\u003e], \n img_width=config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;img_width\u0026#x27;\u003c/span\u003e], \n num_ray_samples=config[\u003cspan class=\"hljs-string\"\u003e\u0026#x27;num_ray_samples\u0026#x27;\u003c/span\u003e])\n fig, ax = plt.subplots(\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e, \u003cspan class=\"hljs-number\"\u003e2\u003c/span\u003e)\n ax[\u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e].imshow(tf.squeeze(image_batch[\u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e]))\n ax[\u003cspan class=\"hljs-number\"\u003e1\u003c/span\u003e].imshow(tf.squeeze(depth_maps[\u003cspan class=\"hljs-number\"\u003e0\u003c/span\u003e]))\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eHere, we're plotting 5 batches (each with one image) and their depth maps.\u003cbr\u003e\nDuring training, the model itself relies on the \u003ccode\u003enerf_render_image_and_depth_tf()\u003c/code\u003e function to convert predictions to images and calculate mean squared error and PSNR for the results. Running this code results in:\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision-7.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003cimg src=\"https://s3.stackabuse.com/media/articles/training-a-neural-radiance-field-nerf-model-with-keras-tensorflow-and-deepvision-8.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eIn this guide - we've summarized some of the key elements of Neural Radiance Fields, as a brief introduction to the subject, followed by loading and preparing the TinyNeRF Dataset in TensorFlow, using \u003ccode\u003etf.data\u003c/code\u003e, and training a NeRF model with the Keras and DeepVision ecosystems.\u003c/p\u003e\n","parent_id":null,"type":"article","visibility":"public","img_feature":null,"is_featured":false,"locale":"en","custom_excerpt":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"comment_id":null,"og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":"In this guide, learn how to perform novel view synthesis and 3D Reconstruction in TensorFlow/Keras and DeepVision, with Python, creating and training Neural Radiance Field (NeRF) models.","read_time_min":17,"published_at":1677756600000,"created_at":1677692405975,"updated_at":1677802627646,"tags":[{"id":9,"name":"python","slug":"python","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431358631000,"updated_at":1431358631000,"_pivot_content_id":1762,"_pivot_tag_id":9,"_pivot_sort_order":0},{"id":75,"name":"machine learning","slug":"machine-learning","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1507305534000,"updated_at":1507305534000,"_pivot_content_id":1762,"_pivot_tag_id":75,"_pivot_sort_order":1},{"id":78,"name":"tensorflow","slug":"tensorflow","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1508009047000,"updated_at":1508009047000,"_pivot_content_id":1762,"_pivot_tag_id":78,"_pivot_sort_order":2},{"id":115,"name":"computer vision","slug":"computer-vision","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1545946018000,"updated_at":1545946018000,"_pivot_content_id":1762,"_pivot_tag_id":115,"_pivot_sort_order":3},{"id":131,"name":"keras","slug":"keras","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1558780443000,"updated_at":1558780443000,"_pivot_content_id":1762,"_pivot_tag_id":131,"_pivot_sort_order":4},{"id":181,"name":"deep learning","slug":"deep-learning","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1595356360000,"updated_at":1595356360000,"_pivot_content_id":1762,"_pivot_tag_id":181,"_pivot_sort_order":5},{"id":256,"name":"DeepVision","slug":"deepvision","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1677802412972,"updated_at":1677802412972,"_pivot_content_id":1762,"_pivot_tag_id":256,"_pivot_sort_order":6},{"id":257,"name":"3D Reconstruction","slug":"3d-reconstruction","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1677802473886,"updated_at":1677802473886,"_pivot_content_id":1762,"_pivot_tag_id":257,"_pivot_sort_order":7},{"id":258,"name":"Volumetric Rendering","slug":"volumetric-rendering","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1677802483265,"updated_at":1677802483265,"_pivot_content_id":1762,"_pivot_tag_id":258,"_pivot_sort_order":8}],"contributors":[{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","_pivot_content_id":1762,"_pivot_user_id":16,"_pivot_role":"author","_pivot_sort_order":0}],"_pivot_user_id":16,"_pivot_content_id":1762},{"id":1751,"title":"Reading and Writing CSV in Bash","slug":"reading-and-writing-csv-in-bash","body_html":"\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003e\u003cem\u003eComma-Separated Values (CSV)\u003c/em\u003e is a widely used file format for storing data in tabular form, where each row represents a record and each column represents a field within that record. The values are separated by a comma, which is why the format is called CSV. CSV is a popular data format for exchanging information between different platforms, programs, and applications, and typially adopts the form of:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003ecol1,col2,col3\nval1,val2,val3\nval1,val2,val3\nval1,val2,val3\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWorking with CSV files is a common task for many people who work in fields such as data analysis, software development, and system administration. Knowing how to read and write CSV files in a Bash environment is essential for automating tasks and processing large amounts of data efficiently.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIn this article, we will look at various ways to read and write CSV files in Bash. We'll explore the different tools available and provide examples of how to use them. Whether you're a beginner or an experienced Bash user, this article will provide you with the information you need to effectively work with CSV files in your shell scripts.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"readingcsvinbash\"\u003eReading CSV in Bash\u003c/h2\u003e\n\u003cp\u003eNow, we'll take a look at how to extract data from a CSV file using tools available in a Bash environment.\u003c/p\u003e\n\u003cp\u003eHere's an example of how to use awk to read a CSV file and extract its data:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-comment\"\u003e# Read the CSV file\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\"\u003ewhile\u003c/span\u003e IFS=\u003cspan class=\"hljs-string\"\u003e\u0026quot;,\u0026quot;\u003c/span\u003e \u003cspan class=\"hljs-built_in\"\u003eread\u003c/span\u003e -r col1 col2 col3\n\u003cspan class=\"hljs-keyword\"\u003edo\u003c/span\u003e\n \u003cspan class=\"hljs-comment\"\u003e# Do something with the columns\u003c/span\u003e\n \u003cspan class=\"hljs-built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;Column 1: \u003cspan class=\"hljs-variable\"\u003e$col1\u003c/span\u003e\u0026quot;\u003c/span\u003e\n \u003cspan class=\"hljs-built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;Column 2: \u003cspan class=\"hljs-variable\"\u003e$col2\u003c/span\u003e\u0026quot;\u003c/span\u003e\n \u003cspan class=\"hljs-built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;Column 3: \u003cspan class=\"hljs-variable\"\u003e$col3\u003c/span\u003e\u0026quot;\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\"\u003edone\u003c/span\u003e \u0026lt; input.csv\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn this example, the while loop reads the CSV file line by line, with each line being separated into columns using the \u003ccode\u003eIFS\u003c/code\u003e variable, which is initially set to \u0026quot;,\u0026quot;. The \u003ccode\u003eread\u003c/code\u003e command then reads the columns into the variables \u003ccode\u003ecol1\u003c/code\u003e, \u003ccode\u003ecol2\u003c/code\u003e, and \u003ccode\u003ecol3\u003c/code\u003e. Finally, we use \u003ccode\u003eecho\u003c/code\u003e to print out the values of each column.\u003c/p\u003e\n\u003cp\u003eAlternatively, one of the most commonly used tools for reading CSV files in Bash is \u003ccode\u003eawk\u003c/code\u003e. \u003ccode\u003eawk\u003c/code\u003e is a powerful text-processing tool that can be used for a variety of tasks, including reading and processing CSV files. Here's an example command that prints the first two columns of a CSV file:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eawk -F \u003cspan class=\"hljs-string\"\u003e\u0026#x27;,\u0026#x27;\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026#x27;{print $1, $2}\u0026#x27;\u003c/span\u003e filename.csv\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn this command, the \u003ccode\u003e-F ','\u003c/code\u003e option specifies that the field separator is a comma, and \u003ccode\u003e{print $1, $2}\u003c/code\u003e tells \u003ccode\u003eawk\u003c/code\u003e to print out the first two columns of the file \u003ccode\u003efilename.csv\u003c/code\u003e. We can modify the command to print other columns or apply conditions on the fields.\u003c/p\u003e\n\u003cp\u003eIf the CSV file has a different delimiter, we can modify the \u003ccode\u003e-F\u003c/code\u003e option to match it. For instance, if the CSV file uses tabs as a separator, we can use \u003ccode\u003e-F '\\t'\u003c/code\u003e to split fields based on tabs. If the CSV file has a header row, we can skip it by using the \u003ccode\u003eNR\u0026gt;1\u003c/code\u003e pattern before the \u003ccode\u003e{print}\u003c/code\u003e statement.\u003c/p\u003e\n\u003cp\u003eIn addition to \u003ccode\u003eawk\u003c/code\u003e, there are other tools available for reading CSV files in Bash, such as \u003ccode\u003esed\u003c/code\u003e. \u003ccode\u003esed\u003c/code\u003e is another text-processing tool that can be used to extract data from a CSV file.\u003c/p\u003e\n\u003cp\u003eWhile both \u003ccode\u003eawk\u003c/code\u003e and \u003ccode\u003esed\u003c/code\u003e are powerful tools, they each have their own pros and cons. \u003ccode\u003eawk\u003c/code\u003e is often considered more flexible and easier to use, while \u003ccode\u003esed\u003c/code\u003e is often considered faster and more efficient. The choice between these tools will depend on the specific requirements of your project.\u003c/p\u003e\n\u003ch2 id=\"writingcsvinbash\"\u003eWriting CSV in Bash\u003c/h2\u003e\n\u003cp\u003eOne of the simplest ways to write CSV files in Bash is to use the \u003ccode\u003eecho\u003c/code\u003e command and redirect its output to a file instead of the standard output pipe. For example:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e#!/bin/bash\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\"\u003e# Write data to the CSV file\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;column1,column2,column3\u0026quot;\u003c/span\u003e \u0026gt; output.csv\n\u003cspan class=\"hljs-built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;data1,data2,data3\u0026quot;\u003c/span\u003e \u0026gt;\u0026gt; output.csv\n\u003cspan class=\"hljs-built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;data4,data5,data6\u0026quot;\u003c/span\u003e \u0026gt;\u0026gt; output.csv\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn this example, we use the echo command to write the header row to the \u003ccode\u003eoutput.csv\u003c/code\u003e file. The \u003ccode\u003e\u0026gt;\u003c/code\u003e operator is used to create a new file or overwrite an existing file, while the \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e operator is used to append data to an existing file. In this case, we use \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e to add additional rows to the \u003ccode\u003eoutput.csv\u003c/code\u003e file.\u003c/p\u003e\n\u003cp\u003eAnother option for writing CSV files in Bash is to use \u003ccode\u003eprintf\u003c/code\u003e. The \u003ccode\u003eprintf\u003c/code\u003e command provides more control over the output format and is often used when writing to a file. For example:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-meta\"\u003e#!/bin/bash\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\"\u003e# Write data to the CSV file using printf\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\"\u003eprintf\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;column1,column2,column3\\n\u0026quot;\u003c/span\u003e \u0026gt; output.csv\n\u003cspan class=\"hljs-built_in\"\u003eprintf\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;data1,data2,data3\\n\u0026quot;\u003c/span\u003e \u0026gt;\u0026gt; output.csv\n\u003cspan class=\"hljs-built_in\"\u003eprintf\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;data4,data5,data6\\n\u0026quot;\u003c/span\u003e \u0026gt;\u0026gt; output.csv\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn this example, we use the \u003ccode\u003eprintf\u003c/code\u003e command to write the header row and data rows to the \u003ccode\u003eoutput.csv\u003c/code\u003e file. The format string \u003ccode\u003e\\n\u003c/code\u003e is used to add a newline character at the end of each row.\u003c/p\u003e\n\u003ch2 id=\"bestpracticesforworkingwithcsvinbash\"\u003eBest Practices for Working with CSV in Bash\u003c/h2\u003e\n\u003cp\u003eWhen working with large or complex CSV files in Bash, we need to follow some best practices to avoid common pitfalls and improve performance. Here are some tips:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eUse \u003ccode\u003eawk\u003c/code\u003e instead of \u003ccode\u003esed\u003c/code\u003e or \u003ccode\u003egrep\u003c/code\u003e for complex CSV processing tasks: \u003ccode\u003eawk\u003c/code\u003e is optimized for handling large text files and can perform complex data transformations, filtering, and formatting. \u003ccode\u003esed\u003c/code\u003e and \u003ccode\u003egrep\u003c/code\u003e are more suitable for simple text manipulation tasks and may be faster.\u003c/li\u003e\n\u003cli\u003eAvoid reading or writing to CSV files in a loop: Reading or writing CSV files in a loop can be slow and inefficient, especially for large files. Instead, try to use a single \u003ccode\u003eawk\u003c/code\u003e or \u003ccode\u003eecho\u003c/code\u003e command that handles all the rows at once.\u003c/li\u003e\n\u003cli\u003eUse a buffer when processing large CSV files: If the CSV file is too large to fit in memory, we can use a buffer to read or write the file in chunks. For example, we can use the \u003ccode\u003ehead\u003c/code\u003e or \u003ccode\u003etail\u003c/code\u003e command to read or write the first or last n lines of a file, or we can use a combination of \u003ccode\u003eawk\u003c/code\u003e and \u003ccode\u003esed\u003c/code\u003e to read or write a specific chunk of rows.\u003c/li\u003e\n\u003cli\u003eClean and format the data before processing: CSV files often contain missing or inconsistent data that can cause errors or unexpected results. Before processing a CSV file in Bash, we should clean and format the data using tools like \u003ccode\u003etr\u003c/code\u003e, \u003ccode\u003esed\u003c/code\u003e, or \u003ccode\u003eawk\u003c/code\u003e. For instance, we can remove extra spaces or newlines, convert data types, or remove special characters.\u003c/li\u003e\n\u003cli\u003eTest the commands on a small sample before applying them to the whole file: When processing a CSV file in Bash, it's important to test the commands on a small sample of the data to make sure they work as expected. We can use the \u003ccode\u003ehead\u003c/code\u003e or \u003ccode\u003etail\u003c/code\u003e command to extract a small subset of the CSV file and test our commands on it.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eIn conclusion, working with CSV files in Bash can be simple and efficient, as long as we follow some best practices and use the right tools.\u003c/p\u003e\n\u003cp\u003eBy using \u003ccode\u003eawk\u003c/code\u003e and \u003ccode\u003eecho\u003c/code\u003e commands, we can read and write CSV files without relying on external tools or libraries. However, we need to be careful when processing large or complex CSV files and avoid common pitfalls, such as reading or writing to files in a loop or ignoring data cleaning and formatting.\u003c/p\u003e\n\u003cp\u003eWith the tips and tricks we've covered in this article, we hope you'll be able to handle CSV files in Bash with ease and confidence.\u003c/p\u003e\n","parent_id":null,"type":"article","visibility":"public","img_feature":null,"is_featured":false,"locale":"en","custom_excerpt":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"comment_id":null,"og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":"In this tutorial, learn how to read and write CSV files in Bash, using `awk`, `sed`, `read` and `echo`, as well as best practices for working with CSV files.","read_time_min":10,"published_at":1677670200000,"created_at":1675194462951,"updated_at":1677693526953,"tags":[{"id":28,"name":"bash","slug":"bash","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431359835000,"updated_at":1431359835000,"_pivot_content_id":1751,"_pivot_tag_id":28,"_pivot_sort_order":1},{"id":29,"name":"unix","slug":"unix","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431359835000,"updated_at":1431359835000,"_pivot_content_id":1751,"_pivot_tag_id":29,"_pivot_sort_order":0}],"contributors":[{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","_pivot_content_id":1751,"_pivot_user_id":16,"_pivot_role":"editor","_pivot_sort_order":1},{"id":94,"name":"Dimitrije Stamenic","slug":"stamd","role_id":4,"img_profile":"https://s3.amazonaws.com/s3.stackabuse.com/media/users/91dc45351236146b499e059557c35823.png","img_cover":null,"bio_html":"","website":"https://www.linkedin.com/in/stamd/","location":"Belgrade, Serbia","facebook":null,"twitter":"stamenic_d","github":"stamd","created_at":1618418516000,"updated_at":1703355178722,"role":"editor","_pivot_content_id":1751,"_pivot_user_id":94,"_pivot_role":"author","_pivot_sort_order":0}],"_pivot_user_id":16,"_pivot_content_id":1751},{"id":1754,"title":"How to Convert JSON to a Python Object","slug":"how-to-convert-json-to-a-python-object","body_html":"\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eIn the world of programming, data is often stored and transmitted in various formats to other parts of an application or other web services. To fascillitate data transfer between services written in different languages and frameworks (such as a Java backend communicating with a Python service, and sending the results to a JavaScript frontend), common formats have been tried, tested and adopted.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eOne of the most commonly used data exchange formats is \u003cstrong\u003e\u003cem\u003eJSON (JavaScript Object Notation)\u003c/em\u003e\u003c/strong\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eIt's human-readable, intuitive, efficient and fast, and quickly took over as the de facto s tandard for data exchange formats with the rise of JavaScript on the web.\u003c/p\u003e\n\u003cp\u003eConverting between JSON and Python objects is useful because it allows Python applications to work with data from external sources or web APIs that use the JSON format. JSON is a lightweight data interchange format that has become the standard for many web-based APIs, making it a popular choice for exchanging data between web applications.\u003c/p\u003e\n\u003cp\u003ePython is a powerful programming language that provides a rich set of data structures and manipulation tools, which can be used to process and analyze JSON data in a variety of ways. For example, Python's built-in dictionaries and lists can be used to store and manipulate JSON objects and arrays in a natural way, while the \u003ccode\u003ejson\u003c/code\u003e module provides methods for serializing and deserializing JSON data to and from Python objects.\u003c/p\u003e\n\u003cp\u003eConversely, converting Python objects to JSON is useful when data needs to be transferred between different systems or applications that may not be written in Python. JSON is a widely-supported format that can be read and written by many programming languages, making it a flexible choice for data interchange.\u003c/p\u003e\n\u003cp\u003eOverall, the ability to convert between JSON and Python objects is an essential skill for any Python developer working with web APIs or external data sources. It allows them to work with data in a way that is natural and intuitive, while still being interoperable with other systems and languages.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIn this article, we'll look at how to convert JSON to Python object.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"convertingjsontopythonobjects\"\u003eConverting JSON to Python Objects\u003c/h2\u003e\n\u003cp\u003ePython provides a built-in \u003ccode\u003ejson\u003c/code\u003e module that makes it easy to convert JSON data to Python objects. The \u003ccode\u003ejson.loads()\u003c/code\u003e function is used to load JSON data from a string, and convert it to a corresponding Python object:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e json\n\njson_string = \u003cspan class=\"hljs-string\"\u003e\u0026#x27;{\u0026quot;name\u0026quot;: \u0026quot;John Doe\u0026quot;, \u0026quot;age\u0026quot;: 30, \u0026quot;is_student\u0026quot;: false}\u0026#x27;\u003c/span\u003e\n\npython_obj = json.loads(json_string)\n\n\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(python_obj)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn this example, we first import the \u003ccode\u003ejson\u003c/code\u003e module. We then define a sample JSON string and store it in the variable \u003ccode\u003ejson_str\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eTo convert the JSON string to a Python object, we use the \u003ccode\u003ejson.loads()\u003c/code\u003e function, which takes a JSON string as input and returns a corresponding Python object. We store the resulting Python object in the variable \u003ccode\u003epython_obj\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eFinally, we print the Python object using the \u003ccode\u003eprint()\u003c/code\u003e function. The output will look like this:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e{\u0026#x27;name\u0026#x27;: \u0026#x27;John Smith\u0026#x27;, \u0026#x27;age\u0026#x27;: 35, \u0026#x27;is_student\u0026#x27;: False}\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003eNote that the JSON boolean value \u003ccode\u003efalse\u003c/code\u003e is converted to a Python boolean value \u003ccode\u003eFalse\u003c/code\u003e. Similarly, JSON \u003ccode\u003enull\u003c/code\u003e value is converted to Python's \u003ccode\u003eNone\u003c/code\u003e.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003ch3 id=\"understandingthejsonloadsfunction\"\u003eUnderstanding the \u003cem\u003ejson.loads()\u003c/em\u003e Function\u003c/h3\u003e\n\u003cp\u003eThe \u003ccode\u003ejson.loads()\u003c/code\u003e function takes a JSON string as input and returns a corresponding Python object.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote::\u003c/strong\u003e It's a common misconception that the method name is \u003cem\u003e\u0026quot;loads\u0026quot;\u003c/em\u003e, as in, the present simple tense of \u0026quot;load\u0026quot;. In fact, the method name is short for \u003cem\u003e\u0026quot;load string\u0026quot;\u003c/em\u003e, reflecting the fact that it's meant to load string-formatted, and supplying a filename won't work. The \u003ccode\u003eload()\u003c/code\u003e method works with filenames.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eIt can also take additional parameters to customize the behavior of the conversion process. Here are some important things to note about this function:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eIt raises a \u003ccode\u003eValueError\u003c/code\u003e exception if the input string is not valid JSON.\u003c/li\u003e\n\u003cli\u003eIt can take a second parameter \u003ccode\u003eobject_hook\u003c/code\u003e which is a function that can modify the decoded object. This function is called for each JSON object decoded and returns the modified object. The \u003ccode\u003eobject_hook\u003c/code\u003e function can be used to parse the JSON object in a custom way.\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003ejson.loads()\u003c/code\u003e function also accepts several other optional parameters that you can read about in the Python documentation.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"handlingerrors\"\u003eHandling Errors\u003c/h3\u003e\n\u003cp\u003eIt's important to handle errors when converting JSON to Python objects, to prevent your program from crashing if the input data is not valid JSON. The \u003ccode\u003ejson.loads()\u003c/code\u003e method raises a \u003ccode\u003eValueError\u003c/code\u003e exception if the input string is not valid JSON, so you should wrap the method call in a \u003ccode\u003etry-except\u003c/code\u003e block to catch this exception and handle it appropriately.\u003c/p\u003e\n\u003cp\u003eHere's an example of how to handle errors when converting JSON to Python objects:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e json\n\n\u003cspan class=\"hljs-comment\"\u003e# Define a JSON string with an error\u003c/span\u003e\njson_str = \u003cspan class=\"hljs-string\"\u003e\u0026#x27;{\u0026quot;name\u0026quot;: \u0026quot;John\u0026quot;, \u0026quot;age\u0026quot;: 30, \u0026quot;city\u0026quot;: \u0026quot;New York\u0026quot;\u0026#x27;\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\"\u003etry\u003c/span\u003e:\n \u003cspan class=\"hljs-comment\"\u003e# Convert the JSON string to a Python object\u003c/span\u003e\n python_obj = json.loads(json_str)\n \u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(python_obj)\n\u003cspan class=\"hljs-keyword\"\u003eexcept\u003c/span\u003e ValueError \u003cspan class=\"hljs-keyword\"\u003eas\u003c/span\u003e e:\n \u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\"\u003e\u0026quot;Error:\u0026quot;\u003c/span\u003e, e)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn this example, we deliberately introduce an error into the JSON string by omitting the closing brace at the end of the object. When we try to convert the string to a Python object, the \u003ccode\u003ejson.loads()\u003c/code\u003e method raises a \u003ccode\u003eValueError\u003c/code\u003e exception. We catch this exception using a \u003ccode\u003etry-except\u003c/code\u003e block, and print an error message to the console.\u003c/p\u003e\n\u003ch2 id=\"convertingpythonobjectstojson\"\u003eConverting Python Objects to JSON\u003c/h2\u003e\n\u003cp\u003eIn addition to converting JSON data to Python objects, the \u003ccode\u003ejson\u003c/code\u003e module in Python also provides a way to convert Python objects to JSON data. This can be useful when working with web APIs that require data to be sent in the JSON format, or when storing data in a JSON file.\u003c/p\u003e\n\u003cp\u003eTo convert a Python object to JSON data, we can use the \u003ccode\u003ejson.dumps()\u003c/code\u003e function, which takes a Python object as input and returns a JSON-formatted string.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e In much the same way \u003ccode\u003eloads()\u003c/code\u003e is short for \u003cem\u003e\u0026quot;load string\u0026quot;\u003c/em\u003e, \u003ccode\u003edumps()\u003c/code\u003e is short for \u003cem\u003e\u0026quot;dump string\u0026quot;\u003c/em\u003e.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eHere is an example:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e json\n\n\u003cspan class=\"hljs-comment\"\u003e# Define a Python dictionary\u003c/span\u003e\npython_obj = {\n \u003cspan class=\"hljs-string\"\u003e\u0026quot;name\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;John\u0026quot;\u003c/span\u003e,\n \u003cspan class=\"hljs-string\"\u003e\u0026quot;age\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-number\"\u003e30\u003c/span\u003e,\n \u003cspan class=\"hljs-string\"\u003e\u0026quot;city\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;New York\u0026quot;\u003c/span\u003e\n}\n\n\u003cspan class=\"hljs-comment\"\u003e# Convert the Python object to a JSON-formatted string\u003c/span\u003e\njson_str = json.dumps(python_obj)\n\n\u003cspan class=\"hljs-comment\"\u003e# Print the JSON string\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(json_str)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn this example, we define a Python dictionary \u003ccode\u003epython_obj\u003c/code\u003e that contains the same data as the JSON string we used in the previous example. We then use the \u003ccode\u003ejson.dumps()\u003c/code\u003e function to convert the Python object to a JSON-formatted string, which we store in the \u003ccode\u003ejson_str\u003c/code\u003e variable. Finally, we print the JSON string to the console.\u003c/p\u003e\n\u003cp\u003eThe output of this program should be a JSON string that looks like this:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e{\u003cspan class=\"hljs-attr\"\u003e\u0026quot;name\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;John\u0026quot;\u003c/span\u003e, \u003cspan class=\"hljs-attr\"\u003e\u0026quot;age\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-number\"\u003e30\u003c/span\u003e, \u003cspan class=\"hljs-attr\"\u003e\u0026quot;city\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;New York\u0026quot;\u003c/span\u003e}\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eBy default, the \u003ccode\u003ejson.dumps()\u003c/code\u003e function produces a compact JSON string with no extra whitespace. However, we can control the output format of the JSON string by using the following parameters:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eindent\u003c/code\u003e: This parameter controls the number of spaces used for indentation. If \u003ccode\u003eindent\u003c/code\u003e is set to a non-negative integer, the output will be formatted with that number of spaces per level of indentation. If \u003ccode\u003eindent\u003c/code\u003e is set to \u003ccode\u003eNone\u003c/code\u003e (the default), the output will be compact with no extra whitespace.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003esort_keys\u003c/code\u003e: This parameter controls whether the output keys in the JSON string should be sorted alphabetically. If \u003ccode\u003esort_keys\u003c/code\u003e is set to \u003ccode\u003eTrue\u003c/code\u003e, the output keys will be sorted. If \u003ccode\u003esort_keys\u003c/code\u003e is set to \u003ccode\u003eFalse\u003c/code\u003e (the default), the output keys will be in the order they were inserted.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eHere is an example that uses the \u003ccode\u003eindent\u003c/code\u003e parameter to produce a pretty-printed JSON string:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eimport\u003c/span\u003e json\n\n\u003cspan class=\"hljs-comment\"\u003e# Define a Python dictionary\u003c/span\u003e\npython_obj = {\n \u003cspan class=\"hljs-string\"\u003e\u0026quot;name\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;John\u0026quot;\u003c/span\u003e,\n \u003cspan class=\"hljs-string\"\u003e\u0026quot;age\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-number\"\u003e30\u003c/span\u003e,\n \u003cspan class=\"hljs-string\"\u003e\u0026quot;city\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;New York\u0026quot;\u003c/span\u003e\n}\n\n\u003cspan class=\"hljs-comment\"\u003e# Convert the Python object to a pretty-printed JSON string\u003c/span\u003e\njson_str = json.dumps(python_obj, indent=\u003cspan class=\"hljs-number\"\u003e4\u003c/span\u003e)\n\n\u003cspan class=\"hljs-comment\"\u003e# Print the JSON string\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\"\u003eprint\u003c/span\u003e(json_str)\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn this example, we set the \u003ccode\u003eindent\u003c/code\u003e parameter to \u003ccode\u003e4\u003c/code\u003e, which causes the output to be indented with four spaces per level of indentation. The output of this program should be a pretty-printed JSON string that looks like this:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e{\n \u003cspan class=\"hljs-attr\"\u003e\u0026quot;name\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;John\u0026quot;\u003c/span\u003e,\n \u003cspan class=\"hljs-attr\"\u003e\u0026quot;age\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-number\"\u003e30\u003c/span\u003e,\n \u003cspan class=\"hljs-attr\"\u003e\u0026quot;city\u0026quot;\u003c/span\u003e: \u003cspan class=\"hljs-string\"\u003e\u0026quot;New York\u0026quot;\u003c/span\u003e\n}\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"bestpractices\"\u003eBest Practices\u003c/h2\u003e\n\u003cp\u003eWhen working with JSON data in Python, it's important to follow some best practices to ensure that the data is properly converted and used in the program. Here are some best practices to consider when working with JSON data in Python.\u003c/p\u003e\n\u003ch3 id=\"validatethejsondata\"\u003eValidate the JSON Data\u003c/h3\u003e\n\u003cp\u003eBefore attempting to convert JSON data to Python objects, it's important to validate the data to ensure that it is well-formed and does not contain any errors. This can be done using online tools or libraries that are specifically designed for JSON validation, such as the \u003ccode\u003ejsonschema\u003c/code\u003e library in Python.\u003c/p\u003e\n\u003ch3 id=\"handleerrorsandexceptions\"\u003eHandle Errors and Exceptions\u003c/h3\u003e\n\u003cp\u003eWhen working with JSON data, it's important to handle errors and exceptions properly. This can be done using Python's built-in error handling mechanisms, such as try-except blocks, to handle errors that may occur during the conversion process.\u003c/p\u003e\n\u003ch3 id=\"useappropriatedatatypes\"\u003eUse Appropriate Data Types\u003c/h3\u003e\n\u003cp\u003eWhen converting JSON data to Python objects, it's important to use appropriate data types to ensure that the data is accurately represented in the program. For example ensuring that JSON numbers are represented as Python float or int objects, and JSON strings are represented as Python string objects.\u003c/p\u003e\n\u003ch3 id=\"understandthelimitationsofthejsonformat\"\u003eUnderstand the Limitations of the JSON Format\u003c/h3\u003e\n\u003cp\u003eWhile JSON is a widely-used data format, it does have some limitations. For example, it does not support certain data types, such as datetime or binary data. In some cases, you may need to serialize some fields in a specific data type, and then parse it later.\u003c/p\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eIn conclusion, JSON is a widely-used data format that is popular for data exchange between different programming languages and platforms. In Python, the built-in \u003ccode\u003ejson\u003c/code\u003e module provides a simple and effective way to convert JSON data to Python objects and vice versa.\u003c/p\u003e\n\u003cp\u003eBy following the best practices we've outlined in this article, such as validating JSON data, handling errors and exceptions, using appropriate data types, and understanding the limitations and use cases of JSON data, developers can effectively work with JSON data in their Python applications. Whether you're working with web APIs, data storage, or data exchange, understanding how to convert JSON to Python objects is an important skill for any Python programmer.\u003c/p\u003e\n","parent_id":null,"type":"article","visibility":"public","img_feature":null,"is_featured":false,"locale":"en","custom_excerpt":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"comment_id":null,"og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":"In this tutorial, learn how to read and write JSON strings to and from Python Objects, using the `json` library, and the `loads()` and `dumps()` methods, with best practices and advice.","read_time_min":13,"published_at":1677670200000,"created_at":1676577994610,"updated_at":1677695632392,"tags":[{"id":9,"name":"python","slug":"python","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431358631000,"updated_at":1431358631000,"_pivot_content_id":1754,"_pivot_tag_id":9,"_pivot_sort_order":0},{"id":25,"name":"json","slug":"json","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431359475000,"updated_at":1431359475000,"_pivot_content_id":1754,"_pivot_tag_id":25,"_pivot_sort_order":1}],"contributors":[{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","_pivot_content_id":1754,"_pivot_user_id":16,"_pivot_role":"editor","_pivot_sort_order":1},{"id":94,"name":"Dimitrije Stamenic","slug":"stamd","role_id":4,"img_profile":"https://s3.amazonaws.com/s3.stackabuse.com/media/users/91dc45351236146b499e059557c35823.png","img_cover":null,"bio_html":"","website":"https://www.linkedin.com/in/stamd/","location":"Belgrade, Serbia","facebook":null,"twitter":"stamenic_d","github":"stamd","created_at":1618418516000,"updated_at":1703355178722,"role":"editor","_pivot_content_id":1754,"_pivot_user_id":94,"_pivot_role":"author","_pivot_sort_order":0}],"_pivot_user_id":16,"_pivot_content_id":1754},{"id":1756,"title":"Guide to the ORDER BY Clause in MySQL","slug":"guide-to-order-by-clause-in-mysql","body_html":"\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eMySQL is a popular open-source database management system that is widely used in web applications. One of the fundamental tasks in working with MySQL is querying data from tables. The \u003ccode\u003eORDER BY\u003c/code\u003e clause is a key feature of MySQL queries that enables you to sort the result set based on one or more columns. By default, MySQL sorts the result set in ascending order based on the specified column(s), but you can also sort the data in descending order or use functions to sort the data.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIn this guide, we'll take a closer look at the \u003ccode\u003eORDER BY\u003c/code\u003e clause in MySQL and how it works. We'll start by discussing what the \u003ccode\u003eORDER BY\u003c/code\u003e clause is and how it works in MySQL. Then, we'll cover the syntax of the \u003ccode\u003eORDER BY\u003c/code\u003e clause and explain the different components of the syntax. We'll also discuss the different types of sorting in MySQL and how to sort data in ascending and descending order. We'll explore how to use the \u003ccode\u003eORDER BY\u003c/code\u003e clause with multiple columns and functions, and how to limit the results of the query. By the end of this guide, you'll have a solid understanding of how to use the \u003ccode\u003eORDER BY\u003c/code\u003e clause in MySQL to sort and limit your query results.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"whatistheorderbyclause\"\u003eWhat is the \u003cem\u003eORDER BY\u003c/em\u003e Clause?\u003c/h2\u003e\n\u003cp\u003eThe \u003ccode\u003eORDER BY\u003c/code\u003e clause is a feature of MySQL that enables you to \u003cstrong\u003esort the result\u003c/strong\u003e of a query based on one or more columns. It allows you to control the order in which the data is presented in the query result.\u003c/p\u003e\n\u003cp\u003eBy default, MySQL sorts the result in ascending order based on the specified column(s). For example, if you have a table of customer names, you can use the \u003ccode\u003eORDER BY\u003c/code\u003e clause to sort the names alphabetically:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e customers\n\u003cspan class=\"hljs-string\"\u003e`ORDER BY`\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ename\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e Don't worry if you don't fully understand the \u003ccode\u003eORDER BY\u003c/code\u003e clause yet. This section provides a brief overview of what you can do with it, and later on, we'll dive into the details of each clause mentioned so that you can master this powerful tool.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eYou can also use the \u003ccode\u003eORDER BY\u003c/code\u003e clause to sort data in descending order. To do this, you can add the \u003ccode\u003eDESC\u003c/code\u003e keyword after the column name:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e customers\n\u003cspan class=\"hljs-string\"\u003e`ORDER BY`\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ename\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIn addition to sorting by a column, you can also \u003cem\u003euse functions to sort\u003c/em\u003e the data. For example, you can use the \u003ccode\u003eLENGTH\u003c/code\u003e function to sort the data by the length of a column:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e customers\n\u003cspan class=\"hljs-string\"\u003e`ORDER BY`\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eLENGTH\u003c/span\u003e(\u003cspan class=\"hljs-keyword\"\u003ename\u003c/span\u003e);\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eNow, let's take a look at the syntax of the \u003ccode\u003eORDER BY\u003c/code\u003e clause in MySQL.\u003c/p\u003e\n\u003ch2 id=\"syntaxoforderbyclause\"\u003eSyntax of \u003cem\u003eORDER BY\u003c/em\u003e Clause\u003c/h2\u003e\n\u003cp\u003eThe syntax of the \u003ccode\u003eORDER BY\u003c/code\u003e clause in MySQL is as follows:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e column_name(s)\n\u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e table_name\n\u003cspan class=\"hljs-keyword\"\u003eWHERE\u003c/span\u003e condition\n\u003cspan class=\"hljs-string\"\u003e`ORDER BY`\u003c/span\u003e column_name1, column_name2, ..., column_nameN \u003cspan class=\"hljs-keyword\"\u003eASC\u003c/span\u003e|\u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cstrong\u003eThe \u003ccode\u003eORDER BY\u003c/code\u003e clause is used at the end of the \u003ccode\u003eSELECT\u003c/code\u003e statement, after the \u003ccode\u003eWHERE\u003c/code\u003e clause (if one is used), and before any \u003ccode\u003eLIMIT\u003c/code\u003e clause (if one is used).\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eLet's break down the components of the syntax:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ecolumn_name(s)\u003c/code\u003e - Specifies the columns to be selected in the query result. You can specify one or more columns separated by commas.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003etable_name\u003c/code\u003e - Specifies the name of the table from which to retrieve the data.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003econdition\u003c/code\u003e - Specifies a condition that must be met for the rows to be included in the result set. This is an optional component.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecolumn_name1, column_name2, ..., column_nameN\u003c/code\u003e - Specifies the columns by which to sort the result set. You can specify one or more columns separated by commas. If you don't specify the sorting order, MySQL will sort the result set in ascending \u003ccode\u003eORDER BY\u003c/code\u003e default.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eASC|DESC\u003c/code\u003e - Specifies the sorting order for the columns. \u003ccode\u003eASC\u003c/code\u003e stands for ascending order (which is the default), and \u003ccode\u003eDESC\u003c/code\u003e stands for descending order.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eHere's an example of the \u003ccode\u003eORDER BY\u003c/code\u003e clause in action:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ename\u003c/span\u003e, age, email\n\u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e customers\n\u003cspan class=\"hljs-keyword\"\u003eWHERE\u003c/span\u003e age \u0026gt; \u003cspan class=\"hljs-number\"\u003e25\u003c/span\u003e\n\u003cspan class=\"hljs-string\"\u003e`ORDER BY`\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ename\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e, age \u003cspan class=\"hljs-keyword\"\u003eASC\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis query will return the \u003ccode\u003ename\u003c/code\u003e, \u003ccode\u003eage\u003c/code\u003e, and \u003ccode\u003eemail\u003c/code\u003e columns from the \u003ccode\u003ecustomers\u003c/code\u003e table for all rows where the \u003ccode\u003eage\u003c/code\u003e is greater than \u003ccode\u003e25\u003c/code\u003e. The result set will be sorted by the \u003ccode\u003ename\u003c/code\u003e column in descending order and then by the \u003ccode\u003eage\u003c/code\u003e column in ascending order.\u003c/p\u003e\n\u003cp\u003eTo sum it all up, the syntax of the \u003ccode\u003eORDER BY\u003c/code\u003e clause consists of specifying the columns to be selected, the table from which to retrieve the data, an optional condition, and the columns by which to sort the result set, along with their sorting order.\u003c/p\u003e\n\u003ch2 id=\"differentwaystosortdatainmysql\"\u003eDifferent Ways to Sort Data in MySQL\u003c/h2\u003e\n\u003cp\u003eThe \u003ccode\u003eORDER BY\u003c/code\u003e clause in MySQL allows you to sort the result set of a query based on one or more columns. You can sort the data in ascending or descending order and use functions to sort the data. Let's take a look at several different ways you can sort data in MySQL.\u003c/p\u003e\n\u003ch3 id=\"sortinginascendingorderinmysql\"\u003eSorting in Ascending Order in MySQL\u003c/h3\u003e\n\u003cp\u003eAs we've seen earlier, MySQL sorts the result set in ascending order based on the specified column(s) by default. To sort the data in ascending order, you can simply specify the column name(s) in the \u003ccode\u003eORDER BY\u003c/code\u003e clause:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e customers\n\u003cspan class=\"hljs-string\"\u003e`ORDER BY`\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ename\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis query will return all the rows from the \u003ccode\u003ecustomers\u003c/code\u003e table and order them by the \u003ccode\u003ename\u003c/code\u003e column in ascending order.\u003c/p\u003e\n\u003ch3 id=\"sortingindescendingorderinmysql\"\u003eSorting in Descending Order in MySQL\u003c/h3\u003e\n\u003cp\u003eTo sort the data in descending order, you can add the \u003ccode\u003eDESC\u003c/code\u003e keyword after the column name in the \u003ccode\u003eORDER BY\u003c/code\u003e clause:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e customers\n\u003cspan class=\"hljs-keyword\"\u003eORDER\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eBY\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ename\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis query will return all the rows from the \u003ccode\u003ecustomers\u003c/code\u003e table and order them by the \u003ccode\u003ename\u003c/code\u003e column in descending order.\u003c/p\u003e\n\u003ch3 id=\"sortingbymultiplecolumns\"\u003eSorting by Multiple Columns\u003c/h3\u003e\n\u003cp\u003eIn MySQL, you can use the \u003ccode\u003eORDER BY\u003c/code\u003e clause to sort the result set of a query based on multiple columns. This can be useful when you want to sort the data by more than one criterion or have a lot of matching entries in a column, and wish to sort by a second criterion, such as \u0026quot;sort alphabetically\u0026quot; and on matching entries, \u0026quot;sort by tenure\u0026quot;.\u003c/p\u003e\n\u003cp\u003eTo use the \u003ccode\u003eORDER BY\u003c/code\u003e clause with multiple columns, simply specify the column names separated by commas in the \u003ccode\u003eORDER BY\u003c/code\u003e clause. MySQL will first sort the data based on the first column specified, and then sort the data based on the second column if there are any ties:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e products\n\u003cspan class=\"hljs-keyword\"\u003eORDER\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eBY\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ecategory\u003c/span\u003e, price \u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis will return all the rows from the \u003ccode\u003eproducts\u003c/code\u003e table and order them by the \u003ccode\u003ecategory\u003c/code\u003e column in ascending order. If there are any ties, MySQL will then sort the tied rows by the \u003ccode\u003eprice\u003c/code\u003e column in descending order.\u003c/p\u003e\n\u003cp\u003eYou can also specify different sorting orders for each column. To sort the data in ascending order for the first column and descending order for the second column, you can use the \u003ccode\u003eASC\u003c/code\u003e and \u003ccode\u003eDESC \u003c/code\u003ekeywords respectively:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e products\n\u003cspan class=\"hljs-keyword\"\u003eORDER\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eBY\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ecategory\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eASC\u003c/span\u003e, price \u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis query will yield us with all the rows from the \u003ccode\u003eproducts\u003c/code\u003e table and order them by the \u003ccode\u003ecategory\u003c/code\u003e column in ascending order. If there are any ties, MySQL will then sort the tied rows by the \u003ccode\u003eprice\u003c/code\u003e column in descending order.\u003c/p\u003e\n\u003ch3 id=\"sortingwithfunctionsinmysql\"\u003eSorting with Functions in MySQL\u003c/h3\u003e\n\u003cp\u003eYou can also use functions and their results to sort data in MySQL. For example, you can use the \u003ccode\u003eLENGTH\u003c/code\u003e function to sort the data by the length of a column:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e customers\n\u003cspan class=\"hljs-keyword\"\u003eORDER\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eBY\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eLENGTH\u003c/span\u003e(\u003cspan class=\"hljs-keyword\"\u003ename\u003c/span\u003e) \u003cspan class=\"hljs-keyword\"\u003eASC\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis will give you all the rows from the \u003ccode\u003ecustomers\u003c/code\u003e table and order them by the length of the \u003ccode\u003ename\u003c/code\u003e column in ascending order.\u003c/p\u003e\n\u003cp\u003eThis query will give us all the rows from the \u003ccode\u003eproducts\u003c/code\u003e table and order them by the length of the \u003ccode\u003ename\u003c/code\u003e column in descending order. The \u003ccode\u003eLENGTH\u003c/code\u003e function is used to determine the length of the \u003ccode\u003ename\u003c/code\u003e column.\u003c/p\u003e\n\u003cp\u003eYou can also use functions in combination with column names in the \u003ccode\u003eORDER BY\u003c/code\u003e clause. This can be useful when you want to sort the data by a combination of a column's value and a calculated value:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e products\n\u003cspan class=\"hljs-keyword\"\u003eORDER\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eBY\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003ecategory\u003c/span\u003e, price / quantity \u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis query will return all the rows from the \u003ccode\u003eproducts\u003c/code\u003e table and order them by the \u003ccode\u003ecategory\u003c/code\u003e column in ascending order. If there are any ties, MySQL will then sort the tied rows by the result of the \u003ccode\u003eprice / quantity\u003c/code\u003e calculation in descending order.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e You can use a variety of functions within the \u003ccode\u003eORDER BY\u003c/code\u003e clause in MySQL, including:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eAggregate functions such as \u003ccode\u003eCOUNT\u003c/code\u003e, \u003ccode\u003eSUM\u003c/code\u003e, \u003ccode\u003eAVG\u003c/code\u003e, \u003ccode\u003eMIN\u003c/code\u003e, and \u003ccode\u003eMAX\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eMathematical functions such as \u003ccode\u003eABS\u003c/code\u003e, \u003ccode\u003eCEILING\u003c/code\u003e, \u003ccode\u003eFLOOR\u003c/code\u003e, \u003ccode\u003eROUND\u003c/code\u003e, and \u003ccode\u003eTRUNCATE\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eString functions such as \u003ccode\u003eLENGTH\u003c/code\u003e, \u003ccode\u003eLEFT\u003c/code\u003e, \u003ccode\u003eRIGHT\u003c/code\u003e, \u003ccode\u003eUPPER\u003c/code\u003e, and \u003ccode\u003eLOWER\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eDate and time functions such as \u003ccode\u003eNOW\u003c/code\u003e, \u003ccode\u003eDATE\u003c/code\u003e, \u003ccode\u003eTIME\u003c/code\u003e, \u003ccode\u003eMONTH\u003c/code\u003e, \u003ccode\u003eYEAR\u003c/code\u003e, and \u003ccode\u003eDAYOFWEEK\u003c/code\u003e.\u003c/li\u003e\n\u003c/ol\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003ch2 id=\"limitingresultsinorderbyclause\"\u003eLimiting Results in \u003cem\u003eORDER BY\u003c/em\u003e Clause\u003c/h2\u003e\n\u003cp\u003eIn MySQL, you can use the \u003ccode\u003eLIMIT\u003c/code\u003e clause with the \u003ccode\u003eORDER BY\u003c/code\u003e clause to limit the number of results returned by a query. This can be useful when you only want to display a certain number of rows or when dealing with large databases.\u003c/p\u003e\n\u003cp\u003eTo use the \u003ccode\u003eLIMIT\u003c/code\u003e clause with the \u003ccode\u003eORDER BY\u003c/code\u003e clause, simply specify the number of rows to return after the \u003ccode\u003eORDER BY\u003c/code\u003e clause:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e products\n\u003cspan class=\"hljs-keyword\"\u003eORDER\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eBY\u003c/span\u003e price \u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\"\u003eLIMIT\u003c/span\u003e \u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis will return the top 5 rows from the \u003ccode\u003eproducts\u003c/code\u003e table sorted by the \u003ccode\u003eprice\u003c/code\u003e column in descending order.\u003c/p\u003e\n\u003cp\u003eYou can also use the \u003ccode\u003eOFFSET\u003c/code\u003e clause with the \u003ccode\u003eLIMIT\u003c/code\u003e clause to skip a certain number of rows before returning the result set:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e products\n\u003cspan class=\"hljs-keyword\"\u003eORDER\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eBY\u003c/span\u003e price \u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\"\u003eLIMIT\u003c/span\u003e \u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eOFFSET\u003c/span\u003e \u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis will give you 5 rows from the \u003ccode\u003eproducts\u003c/code\u003e table sorted by the \u003ccode\u003eprice\u003c/code\u003e column in descending order, starting from the 6th row.\u003c/p\u003e\n\u003cp\u003eIn addition, you can also use variables to set the limit and offset values dynamically:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-keyword\"\u003eSET\u003c/span\u003e @\u003cspan class=\"hljs-keyword\"\u003elimit\u003c/span\u003e = \u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e;\n\u003cspan class=\"hljs-keyword\"\u003eSET\u003c/span\u003e @\u003cspan class=\"hljs-keyword\"\u003eoffset\u003c/span\u003e = \u003cspan class=\"hljs-number\"\u003e5\u003c/span\u003e;\n\u003cspan class=\"hljs-keyword\"\u003eSELECT\u003c/span\u003e * \u003cspan class=\"hljs-keyword\"\u003eFROM\u003c/span\u003e products\n\u003cspan class=\"hljs-keyword\"\u003eORDER\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eBY\u003c/span\u003e price \u003cspan class=\"hljs-keyword\"\u003eDESC\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\"\u003eLIMIT\u003c/span\u003e @\u003cspan class=\"hljs-keyword\"\u003elimit\u003c/span\u003e \u003cspan class=\"hljs-keyword\"\u003eOFFSET\u003c/span\u003e @\u003cspan class=\"hljs-keyword\"\u003eoffset\u003c/span\u003e;\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eThe \u003ccode\u003eORDER BY\u003c/code\u003e clause in MySQL is a powerful tool that allows you to sort the result set of a query in a specific order based on one or more columns. By default, the \u003ccode\u003eORDER BY\u003c/code\u003e clause sorts the result set in ascending order, but you can also specify descending \u003ccode\u003eORDER BY\u003c/code\u003e using the \u003ccode\u003eDESC\u003c/code\u003e keyword.\u003c/p\u003e\n\u003cp\u003eIn addition, you can use the \u003ccode\u003eORDER BY\u003c/code\u003e clause with multiple columns to sort the data by more than one column, and with functions to sort the data based on the results of a function. Furthermore, you can use the \u003ccode\u003eLIMIT\u003c/code\u003e and \u003ccode\u003eOFFSET\u003c/code\u003e clauses to limit the number of results returned by a query.\u003c/p\u003e\n\u003cp\u003eIf you're working with databases, then you simply cannot afford to ignore the \u003ccode\u003eORDER BY\u003c/code\u003e clause in MySQL. It's the boss of sorting data and presenting it in a way that makes sense. And, with the insights you've gained from this guide, you're now the boss of the \u003ccode\u003eORDER BY\u003c/code\u003e clause!\u003c/p\u003e\n","parent_id":null,"type":"article","visibility":"public","img_feature":null,"is_featured":false,"locale":"en","custom_excerpt":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"comment_id":null,"og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":"In this guide, learn everything you need to know about the ORDER BY clause in MySQL - the syntax, where it's supposed to be placed, how to sort by multiple columns, function outputs, etc. with best practices.","read_time_min":15,"published_at":1677670200000,"created_at":1676917402040,"updated_at":1677697291821,"tags":[{"id":66,"name":"sql","slug":"sql","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1456955827000,"updated_at":1456955827000,"_pivot_content_id":1756,"_pivot_tag_id":66,"_pivot_sort_order":1},{"id":117,"name":"mysql","slug":"mysql","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1547661795000,"updated_at":1547661795000,"_pivot_content_id":1756,"_pivot_tag_id":117,"_pivot_sort_order":0}],"contributors":[{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","_pivot_content_id":1756,"_pivot_user_id":16,"_pivot_role":"editor","_pivot_sort_order":1},{"id":94,"name":"Dimitrije Stamenic","slug":"stamd","role_id":4,"img_profile":"https://s3.amazonaws.com/s3.stackabuse.com/media/users/91dc45351236146b499e059557c35823.png","img_cover":null,"bio_html":"","website":"https://www.linkedin.com/in/stamd/","location":"Belgrade, Serbia","facebook":null,"twitter":"stamenic_d","github":"stamd","created_at":1618418516000,"updated_at":1703355178722,"role":"editor","_pivot_content_id":1756,"_pivot_user_id":94,"_pivot_role":"author","_pivot_sort_order":0}],"_pivot_user_id":16,"_pivot_content_id":1756},{"id":1750,"title":"What Does \"2\u003e\u00261\" do on the Command Line?","slug":"what-does-2-1-do-on-the-command-line","body_html":"\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eThe command line is a powerful tool for developers and system administrators. It allows them to perform tasks quickly and efficiently, without having to rely on graphical user interfaces. Understanding the basic concepts of the command line, such as \u003cem\u003eredirections\u003c/em\u003e, is essential for unlocking its full potential. One of these redirections is the \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e operator, which is the focus of this article.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIn this article, we will discuss what \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e is, how it works, and its various use cases. With a deeper understanding of \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e, developers and system administrators can use it to streamline their workflow and troubleshoot issues more effectively.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"whatis21\"\u003eWhat is \u003cem\u003e2\u0026gt;\u0026amp;1\u003c/em\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e is a Shell operator that is used in the command line to redirect \u003ccode\u003estderr\u003c/code\u003e (file descriptor \u003ccode\u003e2\u003c/code\u003e) to \u003ccode\u003estdout\u003c/code\u003e (file descriptor \u003ccode\u003e1\u003c/code\u003e). In other words, it allows any error messages generated by a command to be combined with its standard output and sent to the same destination, such as the terminal or a file.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eFile descriptors\u003c/strong\u003e are a fundamental concept in Unix-based operating systems and are used to identify the source and destination of input and output data. They are assigned integer values, with \u003ccode\u003e0\u003c/code\u003e representing \u003ccode\u003estdin\u003c/code\u003e, \u003ccode\u003e1\u003c/code\u003e representing \u003ccode\u003estdout\u003c/code\u003e, and \u003ccode\u003e2\u003c/code\u003e representing \u003ccode\u003estderr\u003c/code\u003e.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cp\u003eThe \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e operator has a long history and has evolved over time to become a widely used tool in the command line. Its versatility and efficiency have made it a staple for developers and system administrators looking to streamline their workflow and simplify troubleshooting. In the next section, we will dive deeper into how \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e works and its various use cases.\u003c/p\u003e\n\u003ch2 id=\"howdoes21work\"\u003eHow Does \u003cem\u003e2\u0026gt;\u0026amp;1\u003c/em\u003e Work?\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003estderr\u003c/code\u003e and \u003ccode\u003estdout\u003c/code\u003e are two separate data streams in the command line that are used to display the results of a command. \u003ccode\u003estdout\u003c/code\u003e (standard output) is used to display normal output from a command, while \u003ccode\u003estderr\u003c/code\u003e (standard error) is used to display error messages.\u003c/p\u003e\n\u003cp\u003eThe difference between \u003ccode\u003estderr\u003c/code\u003e and \u003ccode\u003estdout\u003c/code\u003e is that \u003ccode\u003estderr\u003c/code\u003e is meant to display error messages, while \u003ccode\u003estdout\u003c/code\u003e is meant to display normal output. By default, \u003ccode\u003estderr\u003c/code\u003e messages are displayed in a different color or are displayed differently in the terminal, making them easier to distinguish from normal output.\u003c/p\u003e\n\u003cp\u003eWith \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e, the \u003ccode\u003estderr\u003c/code\u003e stream is redirected to \u003ccode\u003estdout\u003c/code\u003e, effectively combining the two streams into a single stream of output. This can be \u003cem\u003euseful in several scenarios\u003c/em\u003e, such as debugging scripts, capturing error messages, saving output to a file, or combining output from multiple commands. In the next section, we will explore some of the most common use cases for \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e.\u003c/p\u003e\n\u003ch2 id=\"usecases\"\u003eUse Cases\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e has several useful applications in the command line. Some of the most common use cases are:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eDebugging scripts\u003c/strong\u003e - When writing scripts, it can be difficult to identify errors without having access to stderr messages. By using \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e, developers can redirect \u003ccode\u003estderr\u003c/code\u003e to \u003ccode\u003estdout\u003c/code\u003e, making it easier to identify and fix errors.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eCapturing error messages\u003c/strong\u003e - When running a command, it is important to capture any error messages that are generated. By using \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e, error messages can be redirected to the same destination as the normal output, making them easier to find and analyze.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eSaving output to a file\u003c/strong\u003e - By using \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e in combination with the \u003ccode\u003e\u0026gt;\u003c/code\u003e operator, it is possible to save the combined output of a command to a file. This can be useful for keeping a record of the output or for analyzing it later.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eCombining output from multiple commands\u003c/strong\u003e - When running multiple commands, it can be useful to combine their output into a single stream. By using \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e, the error messages from one command can be redirected to the \u003ccode\u003estdout\u003c/code\u003e of the next command, resulting in a single stream of output.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThese are just a few of the many use cases for \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e. By understanding how it works and its various applications, developers and system administrators can use it to streamline their workflow and simplify troubleshooting.\u003c/p\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eIn conclusion, \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e is a handy shell operator that is widely used in the command line. It makes it easy for developers and system administrators to redirect \u003ccode\u003estderr\u003c/code\u003e (file descriptor \u003ccode\u003e2\u003c/code\u003e) to \u003ccode\u003estdout\u003c/code\u003e (file descriptor \u003ccode\u003e1\u003c/code\u003e), combining error messages with normal output into a single stream.\u003c/p\u003e\n\u003cp\u003eUnderstanding \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e is key to unlocking the full potential of the command line and making work a breeze. With its many uses, such as debugging scripts, capturing error messages, saving output to a file, and combining output from multiple commands, \u003ccode\u003e2\u0026gt;\u0026amp;1\u003c/code\u003e is a great tool to have in your toolbox. By using it effectively, you can simplify troubleshooting and get things done faster and more efficiently.\u003c/p\u003e\n","parent_id":null,"type":"article","visibility":"public","img_feature":null,"is_featured":false,"locale":"en","custom_excerpt":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"comment_id":null,"og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":"In this short tutorial, learn what \"2\u003e\u00261\" does in the Command Line on Linux.","read_time_min":6,"published_at":1673350200000,"created_at":1675165912151,"updated_at":1675381133077,"tags":[{"id":29,"name":"unix","slug":"unix","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431359835000,"updated_at":1431359835000,"_pivot_content_id":1750,"_pivot_tag_id":29,"_pivot_sort_order":0}],"contributors":[{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","_pivot_content_id":1750,"_pivot_user_id":16,"_pivot_role":"editor","_pivot_sort_order":1},{"id":94,"name":"Dimitrije Stamenic","slug":"stamd","role_id":4,"img_profile":"https://s3.amazonaws.com/s3.stackabuse.com/media/users/91dc45351236146b499e059557c35823.png","img_cover":null,"bio_html":"","website":"https://www.linkedin.com/in/stamd/","location":"Belgrade, Serbia","facebook":null,"twitter":"stamenic_d","github":"stamd","created_at":1618418516000,"updated_at":1703355178722,"role":"editor","_pivot_content_id":1750,"_pivot_user_id":94,"_pivot_role":"author","_pivot_sort_order":0}],"_pivot_user_id":16,"_pivot_content_id":1750},{"id":1749,"title":"How to Grep Recursively in Bash","slug":"how-to-grep-recursively-in-bash","body_html":"\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eGrep is a powerful tool in the Unix world that allows you to search for specific text within files or even directories. It is widely used for log analysis, code review, and many other tasks that require searching for text. In Bash, you can use \u003ccode\u003egrep\u003c/code\u003e to search for specific text in a single file, but what if you want to search for text in multiple files in a directory and its subdirectories?\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eThis is where recursive \u003ccode\u003egrep\u003c/code\u003e comes in.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eRecursive \u003ccode\u003egrep\u003c/code\u003e is a feature in Bash that enables you to search for text within all files in a directory and its subdirectories. This is particularly useful when you have a large number of files or when you want to search for text in all files under a specific directory. With recursive \u003ccode\u003egrep\u003c/code\u003e, you can easily search for specific text in all files, without having to open each file individually.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eIn this article, we will cover the basic syntax for recursive \u003ccode\u003egrep\u003c/code\u003e, practical use cases, and advanced options to help you become more proficient in using this powerful tool. This article will provide you with the knowledge you need to effectively use recursive \u003ccode\u003egrep\u003c/code\u003e in Bash.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"basicsyntaxforrecursivegrep\"\u003eBasic Syntax for Recursive Grep\u003c/h2\u003e\n\u003cp\u003eLet's take a quick look at the basic syntax for using \u003ccode\u003egrep\u003c/code\u003e to search for text recursively in Bash:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003egrep -r \u0026lt;pattern\u0026gt; \u0026lt;directory\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eNow, we can break down the components of this command:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003egrep\u003c/code\u003e - This is the command that you use to search for text\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-r\u003c/code\u003e - This is the option that tells \u003ccode\u003egrep\u003c/code\u003e to \u003cem\u003esearch recursively\u003c/em\u003e. It searches through all the files in the target directory, including subdirectories.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e\u0026lt;pattern\u0026gt;\u003c/code\u003e - This is the text or pattern that you want to search for. You can use regular expressions to specify the pattern.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e\u0026lt;directory\u0026gt;\u003c/code\u003e - This is the target directory that you want to search in. You can specify a relative or absolute path to the directory.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eHere's an example of how you might use this syntax in a real-world scenario:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003egrep -r \u003cspan class=\"hljs-string\"\u003e\u0026quot;error\u0026quot;\u003c/span\u003e /var/\u003cspan class=\"hljs-built_in\"\u003elog\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eThis command will search for the word \u003ccode\u003e\u0026quot;error\u0026quot;\u003c/code\u003e in all files within the \u003ccode\u003e/var/log\u003c/code\u003e directory, including subdirectories. The result of this command will display the name of the file and the line of text that contains the word \u003ccode\u003e\u0026quot;error\u0026quot;\u003c/code\u003e.\u003c/p\u003e\n\n \u003cdiv class=\"alert alert-note\"\u003e\n \u003cdiv class=\"flex\"\u003e\n \n \u003cdiv class=\"flex-shrink-0 mr-3\"\u003e\n \u003cimg src=\"/assets/images/icon-information-circle-solid.svg\" class=\"icon\" aria-hidden=\"true\" /\u003e\n \u003c/div\u003e\n \n \u003cdiv class=\"w-full\"\u003e\n \u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e The basic syntax for recursive \u003ccode\u003egrep\u003c/code\u003e is the same for most Unix-based systems. However, some systems may have different options or variations of the command. It's always a good idea to consult the documentation for your specific system to make sure you are using the correct syntax.\u003c/p\u003e\n\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003ch2 id=\"practicalusecasesofthegrepcommand\"\u003ePractical Use Cases of the grep Command\u003c/h2\u003e\n\u003cp\u003eRecursive \u003ccode\u003egrep\u003c/code\u003e is a versatile tool that can be used in a variety of situations. Here are some practical use cases for recursive \u003ccode\u003egrep\u003c/code\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eSearching for specific text in all files under a directory\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eIf you have a directory with multiple files and you want to search for a specific piece of text, you can use recursive grep to search through all the files in the directory and its subdirectories\u003c/li\u003e\n\u003cli\u003eThis can be useful for tasks such as log analysis or code review\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eSearching for specific text in files with a specific extension\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eIf you want to search for text in only specific types of files, you can use the \u003ccode\u003e--include\u003c/code\u003e option in combination with a file extension\u003c/li\u003e\n\u003cli\u003eFor example, you might use \u003ccode\u003e--include=*.log\u003c/code\u003e to search only in files with a \u003ccode\u003e.log\u003c/code\u003e extension\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eSearching for specific text in hidden files\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eIf you need to search for text in hidden files, you can use the \u003ccode\u003e-a\u003c/code\u003e option to include hidden files in the search\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFor example, the following command will search for the word \u003ccode\u003e\u0026quot;error\u0026quot;\u003c/code\u003e in all \u003ccode\u003e.log\u003c/code\u003e files, including hidden files, in the \u003ccode\u003e/var/log\u003c/code\u003e directory and its subdirectories:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003egrep -r -a \u003cspan class=\"hljs-string\"\u003e\u0026quot;error\u0026quot;\u003c/span\u003e /var/\u003cspan class=\"hljs-built_in\"\u003elog\u003c/span\u003e --include=*.\u003cspan class=\"hljs-built_in\"\u003elog\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"advancedoptions\"\u003eAdvanced Options\u003c/h2\u003e\n\u003cp\u003eWhile the basic syntax for recursive \u003ccode\u003egrep\u003c/code\u003e is simple, there are many advanced options that you can use to further customize your search. Here are some of the most commonly used advanced options for recursive grep:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003e-i\u003c/code\u003e - This option makes \u003ccode\u003egrep\u003c/code\u003e \u003cem\u003ecase-insensitive\u003c/em\u003e, meaning that it will match the search pattern regardless of the case\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFor example, \u003ccode\u003egrep -ri \u0026quot;error\u0026quot; /var/log\u003c/code\u003e will match both \u003ccode\u003e\u0026quot;error\u0026quot;\u003c/code\u003e and \u003ccode\u003e\u0026quot;Error\u0026quot;\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003e-l\u003c/code\u003e - This option tells \u003ccode\u003egrep\u003c/code\u003e to \u003cem\u003eonly display the names of the files\u003c/em\u003e that contain the search pattern, rather than the actual lines of text\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFor example, \u003ccode\u003egrep -rl \u0026quot;error\u0026quot; /var/log\u003c/code\u003e will display a list of all files in the \u003ccode\u003e\u0026quot;/var/log\u0026quot;\u003c/code\u003e directory that contain the word \u003ccode\u003e\u0026quot;error\u0026quot;\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003e-v\u003c/code\u003e: This option \u003cem\u003einverts the search\u003c/em\u003e, meaning that it will display all lines of text that do not match the search pattern\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFor example, \u003ccode\u003egrep -rv \u0026quot;error\u0026quot; /var/log\u003c/code\u003e will display all lines of text in the \u003ccode\u003e/var/log\u003c/code\u003e directory that do not contain the word \u003ccode\u003e\u0026quot;error\u0026quot;\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003e-n\u003c/code\u003e: This option displays the \u003cem\u003eline number of each match in the file\u003c/em\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFor example, \u003ccode\u003egrep -rn \u0026quot;error\u0026quot; /var/log\u003c/code\u003e will display the line number for each line that contains the word \u003ccode\u003e\u0026quot;error\u0026quot;\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ccode\u003e--exclude\u003c/code\u003e: This option allows you to \u003cem\u003eexclude specific files or directories\u003c/em\u003e from the search\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFor example, \u003ccode\u003egrep -r --exclude=*.log \u0026quot;error\u0026quot; /var/log\u003c/code\u003e will search for the word \u003ccode\u003e\u0026quot;error\u0026quot;\u003c/code\u003e in all files in the \u003ccode\u003e/var/log\u003c/code\u003e directory, excluding files with a \u003ccode\u003e.log\u003c/code\u003e extension\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThese are just a few examples of the many advanced options that you can use with recursive \u003ccode\u003egrep\u003c/code\u003e. By combining these options, you can create complex searches that match your specific needs. Whether you are searching for text in logs, code, or other types of files, the advanced options for recursive \u003ccode\u003egrep\u003c/code\u003e can help you get the results you need.\u003c/p\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eAll-in-all, recursive \u003ccode\u003egrep\u003c/code\u003e is a powerful tool in the bash shell that allows you to search for text in multiple files, including files in subdirectories. With its simple syntax and numerous advanced options, recursive \u003ccode\u003egrep\u003c/code\u003e can be used in a variety of situations, from searching for specific text in logs to searching for code in your project's source files. Whether you are a beginner or an advanced user, recursive \u003ccode\u003egrep\u003c/code\u003e is an important tool to have in your toolbox for any task that requires searching for text in multiple files.\u003c/p\u003e\n","parent_id":null,"type":"article","visibility":"public","img_feature":null,"is_featured":false,"locale":"en","custom_excerpt":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"comment_id":null,"og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":"In this short tutorial, learn how to search for text recursively, in a given directory, using the grep command, starting with the basic syntax, and going through advanced flags and practical use cases.","read_time_min":9,"published_at":1673263800000,"created_at":1675159299032,"updated_at":1675381582016,"tags":[{"id":28,"name":"bash","slug":"bash","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431359835000,"updated_at":1431359835000,"_pivot_content_id":1749,"_pivot_tag_id":28,"_pivot_sort_order":0},{"id":29,"name":"unix","slug":"unix","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431359835000,"updated_at":1431359835000,"_pivot_content_id":1749,"_pivot_tag_id":29,"_pivot_sort_order":1}],"contributors":[{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","_pivot_content_id":1749,"_pivot_user_id":16,"_pivot_role":"editor","_pivot_sort_order":0},{"id":94,"name":"Dimitrije Stamenic","slug":"stamd","role_id":4,"img_profile":"https://s3.amazonaws.com/s3.stackabuse.com/media/users/91dc45351236146b499e059557c35823.png","img_cover":null,"bio_html":"","website":"https://www.linkedin.com/in/stamd/","location":"Belgrade, Serbia","facebook":null,"twitter":"stamenic_d","github":"stamd","created_at":1618418516000,"updated_at":1703355178722,"role":"editor","_pivot_content_id":1749,"_pivot_user_id":94,"_pivot_role":"author","_pivot_sort_order":1}],"_pivot_user_id":16,"_pivot_content_id":1749},{"id":1748,"title":"How to Get the Source Directory of a Bash Script","slug":"how-to-get-the-source-directory-of-a-bash-script","body_html":"\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eGetting the source directory of a Bash script is an important topic for anyone who is looking to develop robust and reliable Bash scripts. Understanding how to retrieve the source directory of a script can make it easier to manage and organize your code. Whether you're a beginner or an experienced shell script programmer, it's essential to understand this concept.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eThe article will cover the basics of the \u003ccode\u003e$0\u003c/code\u003e parameter in Bash, which holds the name of the script. We will then discuss the \u003ccode\u003edirname\u003c/code\u003e command, which is used to extract the directory portion of a file path. Finally, we will put everything together to demonstrate how to get the source directory of a script using these tools.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eSo, let's dive in and learn how to get the source directory of a Bash script.\u003c/p\u003e\n\u003ch2 id=\"understandingthe0parameter\"\u003eUnderstanding the \u003cem\u003e$0\u003c/em\u003e Parameter\u003c/h2\u003e\n\u003cp\u003eThe \u003ccode\u003e$0\u003c/code\u003e parameter in Bash holds the name of the script that is currently running. It is a special parameter that can be used to retrieve the name of the script at runtime. This information can be useful for various purposes, such as printing the name of the script or using it to determine the source directory.\u003c/p\u003e\n\u003cp\u003eHere is an example of using the \u003ccode\u003e$0\u003c/code\u003e parameter to print the name of the script. Say the following is the content of the Bash script called \u003ccode\u003etest.sh\u003c/code\u003e and that it is located in the \u003ccode\u003e/home/username/Desktop/scripts\u003c/code\u003e folder:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e\u003cspan class=\"hljs-built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;The name of the script is: \u003cspan class=\"hljs-variable\"\u003e$0\u003c/span\u003e\u0026quot;\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWhen run, this script will output the following:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eThe name of the script is: /home/username/Desktop/scripts/test.sh\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAs you can see, the \u003ccode\u003e$0\u003c/code\u003e parameter holds the full path to the script, \u003cem\u003eincluding the script name itself\u003c/em\u003e. This information can be used in combination with the \u003ccode\u003edirname\u003c/code\u003e command to retrieve the source directory of the script, as we will see in the next section.\u003c/p\u003e\n\u003ch2 id=\"usingthedirnamecommand\"\u003eUsing the \u003cem\u003edirname\u003c/em\u003e Command\u003c/h2\u003e\n\u003cp\u003eThe \u003ccode\u003edirname\u003c/code\u003e command in Bash is used to extract the directory portion of a file path. It takes a file path as an argument and returns the directory portion of that path.\u003c/p\u003e\n\u003cp\u003eHere is an example of using the \u003ccode\u003edirname\u003c/code\u003e command to extract the directory portion of a file path:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003e$ dirname /home/username/Desktop/scripts/test.sh\n\u003cspan class=\"hljs-comment\"\u003e# Output: /home/username/Desktop/scripts\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAs you can see, the \u003ccode\u003edirname\u003c/code\u003e command returns the directory portion of the file path, excluding the file name itself. This information can be used in combination with the \u003ccode\u003e$0\u003c/code\u003e parameter to retrieve the source directory of a script.\u003c/p\u003e\n\u003ch2 id=\"puttingitalltogether\"\u003ePutting It All Together\u003c/h2\u003e\n\u003cp\u003eNow that we have a basic understanding of the \u003ccode\u003e$0\u003c/code\u003e parameter and the \u003ccode\u003edirname\u003c/code\u003e command, let's put everything together to demonstrate how to get the source directory of a script.\u003c/p\u003e\n\u003cp\u003eHere is a complete example that uses both the \u003ccode\u003e$0\u003c/code\u003e parameter and the \u003ccode\u003edirname\u003c/code\u003e command to retrieve the source directory of a script (which is called \u003ccode\u003eexample.sh\u003c/code\u003e):\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003esrc_dir=$(dirname \u003cspan class=\"hljs-string\"\u003e\u0026quot;\u003cspan class=\"hljs-variable\"\u003e$0\u003c/span\u003e\u0026quot;\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;The name of the script is: \u003cspan class=\"hljs-variable\"\u003e$0\u003c/span\u003e\u0026quot;\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"hljs-string\"\u003e\u0026quot;Source directory of the script: \u003cspan class=\"hljs-variable\"\u003e$src_dir\u003c/span\u003e\u0026quot;\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eWhen run, this script will output the following:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"hljs\"\u003eThe name of the script is: /home/username/Desktop/scripts/example.sh\nSource directory of the script: /home/username/Desktop/scripts\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eAs you can see, this script uses the \u003ccode\u003e$0\u003c/code\u003e parameter to retrieve the full path to the script and then uses the \u003ccode\u003edirname\u003c/code\u003e command to extract the directory portion of that path. This information is stored in the \u003ccode\u003esrc_dir\u003c/code\u003e variable, which can then be used in your script as needed.\u003c/p\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eIn conclusion, getting the source directory of a Bash script is a straightforward process that involves the use of the \u003ccode\u003e$0\u003c/code\u003e parameter and the \u003ccode\u003edirname\u003c/code\u003e command. By understanding these two concepts, you have the ability to retrieve the source directory of any script and use it in your code as needed. Whether you're building simple scripts or complex applications, this information is essential for creating reliable and efficient Bash scripts.\u003c/p\u003e\n","parent_id":null,"type":"article","visibility":"public","img_feature":null,"is_featured":false,"locale":"en","custom_excerpt":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"comment_id":null,"og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":"In this short tutorial, learn how to get the source directory of a bash script, using the $0 parameter, and the dirname command.","read_time_min":5,"published_at":1673004600000,"created_at":1675103837636,"updated_at":1687449594420,"tags":[{"id":28,"name":"bash","slug":"bash","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431359835000,"updated_at":1431359835000,"_pivot_content_id":1748,"_pivot_tag_id":28,"_pivot_sort_order":0},{"id":29,"name":"unix","slug":"unix","img_cover":null,"description_html":"","og_image":null,"og_title":null,"og_description":null,"twitter_image":null,"twitter_title":null,"twitter_description":null,"meta_title":null,"meta_description":null,"inject_header":null,"inject_footer":null,"canonical_url":null,"color":null,"created_at":1431359835000,"updated_at":1431359835000,"_pivot_content_id":1748,"_pivot_tag_id":29,"_pivot_sort_order":1}],"contributors":[{"id":16,"name":"David Landup","slug":"david","role_id":2,"img_profile":"//s3.stackabuse.com/media/users/865cd7d217ea11c9d9555c4f666e2d73.jpg","img_cover":null,"bio_html":"\u003cp\u003eEntrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.\u003c/p\u003e\n\u003cp\u003eGreat passion for accessible education and promotion of reason, science, humanism, and progress.\u003c/p\u003e\n","website":"https://www.linkedin.com/in/david-landup-859455144/","location":"Serbia","facebook":"","twitter":"","github":null,"created_at":1534532687000,"updated_at":1692629560355,"role":"editor","_pivot_content_id":1748,"_pivot_user_id":16,"_pivot_role":"editor","_pivot_sort_order":1},{"id":94,"name":"Dimitrije Stamenic","slug":"stamd","role_id":4,"img_profile":"https://s3.amazonaws.com/s3.stackabuse.com/media/users/91dc45351236146b499e059557c35823.png","img_cover":null,"bio_html":"","website":"https://www.linkedin.com/in/stamd/","location":"Belgrade, Serbia","facebook":null,"twitter":"stamenic_d","github":"stamd","created_at":1618418516000,"updated_at":1703355178722,"role":"editor","_pivot_content_id":1748,"_pivot_user_id":94,"_pivot_role":"author","_pivot_sort_order":0}],"_pivot_user_id":16,"_pivot_content_id":1748}],"content_count":"631"},"page":1,"error":null},"__N_SSP":true},"page":"/author/[...slug]","query":{"slug":["david"]},"buildId":"1739247265773","isFallback":false,"isExperimentalCompile":false,"gssp":true,"scriptLoader":[]}</script></body></html>