Django Series

Lesson 1: Start

Lesson 2: Git

Lesson 3: MVC

Lesson 4: Forms

Lesson 5: Models

Appendix i: Setup

Appendix ii: Shell

Appendix iii: TDD

Command Line Tricks for Ridiculously Fast Django Development

Command Line Icon

 

The command line is one of the most important tool in your arsenal. Knowing it well and be fast with it will seriously boost your performance and effectiveness. One side of that is knowing the commands well, the other side is aliases and custom variables.

 

We will focus on the aliases today with the most important shortcuts. An alias is giving another name to command, possibly a much shorter one. For example you want a faster way to invoke Python interpreter. Instead of “python3” you could just type “p”. The command would go this way:

alias p=python3

 

This setting will cease to exists when you exit the terminal. You can make it permanent if you set them in the .bashrc file in your home directory. Open up ~/.bashrc with your editor. I use nano:

nano ~/.bashrc

 

Head to the bottom of the file and copy the following:

*** ~/.bashrc ***

#my custom aliases

alias v=”source ../virtualenv/bin/activate”

alias dea=”deactivate”

alias r=”python3 manage.py runserver”

alias te=”python3 manage.py test”

alias c=”clear”

alias mdkir=”mkdir”

alias ..=”cd ..”

alias ….=”cd ../..”

alias …...=”cd ../../..”

 

#my custom variables

tut=”~/Tutorial/DjangoTutorial/source” // Replace it where your working directory is

 

If you haven't followed along with the tutorial here is the way to set it up. Clone the exercise3 branch.

 

Now, let's play around with these new tricks. Navigate into the $tut directory:

cd $tut

 

That gets you to the ~/Tutorial/DjangoTutorial/source directory from anywhere on your computer.

 

Change directory to the grandparent. In my case Tutorial/ folder.

....

 

Let's say you want to clone your DjangoTutorial project.

mkdir Testrepo

cd // Press Alt+.

 

Alt + . takes the last argument of the last command you used. In this case “Testrepo”. So your command autocompleted:

cd Testrepo

 

Clone $tut repository in our folder. Don't forget the dot at the end:

git clone $tut .

 

Should see this output:

Cloning into '.'...

done.

 

Check our files:

ls

 

Output:

main manage.py MyTutorial requirements.txt

 

This is identical, but if you really want to make sure:

diff $tut .

Output:

Common subdirectories: /home/david/Tutorial/DjangoTutorial/source/.git and ./.git

Common subdirectories: /home/david/Tutorial/DjangoTutorial/source/main and ./main

Common subdirectories: /home/david/Tutorial/DjangoTutorial/source/MyTutorial and ./MyTutorial

 

Okay, you changed your mind, and want to erase this repo. Change back to parent directory.

..

 

Delete with the recursive (r) and forced (f) options. Meaning, that it goes through all subdirectories and files and erase everything in it's path. Forced means, that you don't have to tell “yes” everytime there is a sensitive file. Needless to say, use this command with extreme caution!

rm Testrepo -r -f

 

Before we go back. Let me demonstrate the most common, single important command you will use, if you haven't already. Tab as autocomplete.

cat $tut/main/mo // Press Tab

 

You should see your command expanded and autocompleted.

cat /home/david/Tutorial/DjangoTutorial/source/main/models.py

This goes for any file or folder. Just provide with enough letter for the computer to be able to guess.

 

Let's move back to our $tut folder.

cd $tut

 

Activate virtualenv.

v

 

Command line should get into virtual environment mode:

(virtualenv) david@my-machine:~/Tutorial/DjangoTutorial/source$

 

Let's run the development server:

r

 

Output:

Performing system checks...

 

System check identified no issues (0 silenced).

November 12, 2016 - 15:40:40

Django version 1.10, using settings 'MyTutorial.settings'

Starting development server at http://127.0.0.1:8000/

Quit the server with CONTROL-C.

 

Press Ctrl + C, to escape. One of the most frequent command I also use is “clear”. Lot of times you will need it to not get confused by earlier outputs and to keep your sanity.

c

 

Testing will also need to be repeated several dozens of times.

te

 

Output:

Creating test database for alias 'default'...

....

----------------------------------------------------------------------

Ran 4 tests in 0.020s

 

OK

Destroying test database for alias 'default'...

 

If you are wondering why don't I used only the “t” letter, it's because I keep it for special occasions. Let's say, you accidentally modify the article variables in index.html the following way:

***main/templates/index.html***

...

<p>Hello World</p>

<p>{{ article }}</p>

<p>{{ article }}</p>

...

Run the test:

te

 

Output:

Creating test database for alias 'default'...

...F

======================================================================

FAIL: test_index_html_displays_article (main.tests.ModelTest)

...

So you need to pinpoint the cause of the error (let's pretend, you don't know what is the cause of the problem). You can run only this one failing test, like so:

python3 manage.py test main.tests.ModelTest.test_index_html_displays_article

(Run test from main application, tests module, ModelTest class, test_index_html_displays_article function)

 

That's unnecessary long and difficult to remember. Easier to set up an alias:

alias t=”python3 manage.py test main.tests.ModelTest.test_index_html_displays_article”

 

Next time you need to run, just type:

t

 

Remember if you close your terminal window, this alias won't be remembered next time.

 

So you figured there is something going on with the “article” object. Let's check all the files that has this word in them and the exact lines.

grep -r article

 

Output:

main/views.py: article = Article.objects.last()

main/views.py: return render(request,'index.html',{'article':article,})

main/migrations/0002_auto_20161109_1542.py: model_name='article',

Binary file main/migrations/__pycache__/0002_auto_20161109_1542.cpython-34.pyc matches

main/templates/index.html: <p>{{ article }}</p>

main/templates/index.html: <p>{{ article }}</p>

Binary file main/__pycache__/views.cpython-34.pyc matches

Binary file main/__pycache__/tests.cpython-34.pyc matches

main/tests.py: self.article = Article.objects.all().filter(title=self.test_title)

main/tests.py: self.article.delete()

main/tests.py: self.assertEqual(self.article.values()[0]['text'],self.test_body)

main/tests.py: def test_index_html_displays_article(self):

 

Okay, so you narrowed down the problem. The cause of error must be in index.html, tests.py or views.py. You also remember, that last time you committed, all tests were passing. So let's check git diff to what has been modified.

Git diff

 

Output:

diff --git a/main/templates/index.html b/main/templates/index.html

index d95f9cf..1ac081a 100644

--- a/main/templates/index.html

+++ b/main/templates/index.html

@@ -6,7 +6,7 @@

</head>

<body>

<p>Hello World</p>

- <p>{{ article.title }}</p>

- <p>{{ article.text }}</p>

+ <p>{{ article }}</p>

+ <p>{{ article }}</p>

</body>

</html>

 

Oh! Now, you see what happened. Instead of changing the lines directly, you reverse all changes through git.

Git reset --hard

 

Output:

HEAD is now at 1452ef7 Article model is displayed on home page

 

It was enough for today, let's change back from virtualenv:

dea

 

Congratulations!

 

You learned to be savvy with the command line shortcuts and possibly will be seriously faster in the future! Remember the file .bashrc and update it regularly to your workflow. Let me know in the comment section if you have any questions.

 

See you next time!

 

Tags: beginner , django , command line , CLI , tutorial , unit test