<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: foadlind</title>
    <description>The latest articles on DEV Community by foadlind (@foadlind).</description>
    <link>https://dev.to/foadlind</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F333510%2Fea16818c-a295-4a0f-aed2-11ff7ebc7c2d.jpeg</url>
      <title>DEV Community: foadlind</title>
      <link>https://dev.to/foadlind</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/foadlind"/>
    <language>en</language>
    <item>
      <title>Recover a deleted local branch</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Tue, 08 Feb 2022 07:02:04 +0000</pubDate>
      <link>https://dev.to/foadlind/recover-a-deleted-local-branch-18kf</link>
      <guid>https://dev.to/foadlind/recover-a-deleted-local-branch-18kf</guid>
      <description>&lt;p&gt;If you have accidentally deleted a branch that was never pushed to a remote, you can easily recover it in Git. &lt;br&gt;
You'll need help from a useful Git utility called &lt;code&gt;reflog&lt;/code&gt;. Let's show you how to do it:&lt;/p&gt;

&lt;p&gt;Suppose I have a local branch called &lt;code&gt;feature_1&lt;/code&gt;, in which I have made a commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* ef640e4 (feature_1) Add settings flag for feature_1
* 4015b6f (HEAD -&amp;gt; main) Provide default for product size
* d8dc31c Add db info to settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I, accidentally, delete the &lt;code&gt;feature_1&lt;/code&gt; branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git branch -D feature_1
Deleted branch feature_1 (was ef640e4).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now all my work in that branch is gone 😱:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* 4015b6f (HEAD -&amp;gt; main) Provide default for product size.
* d8dc31c Add db info to settings.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since I had not yet pushed the branch, I don't have a copy of it on the remote, so I have to resort to &lt;code&gt;reflog&lt;/code&gt;. Git always keeps a log of your activities in the repository. &lt;/p&gt;

&lt;p&gt;By activities, I mean anything that has to do with Git. So if&lt;br&gt;
you have committed anything, made a branch, stashed anything, it will be notes in the &lt;code&gt;reflog&lt;/code&gt;. &lt;a href="https://git-scm.com/docs/git-reflog"&gt;Git documentation&lt;/a&gt; defines it like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reference logs, or "reflogs", record when the tips of branches and other references were updated in the local repository.Reflogs are useful in various Git commands, to specify the old value of a reference.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So let's use it in our case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git reflog
4015b6f (HEAD -&amp;gt; main) HEAD@{0}: checkout: moving from feature_1 to main
ef640e4 HEAD@{1}: commit: Add settings flag for feature_1
4015b6f (HEAD -&amp;gt; main) HEAD@{2}: checkout: moving from main to feature_1
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There it is! Our last commit in &lt;code&gt;feature_1&lt;/code&gt; branch: &lt;code&gt;ef640e4 HEAD@{1}: commit: Add settings flag for feature_1&lt;/code&gt;. That is&lt;br&gt;
the location in our commit tree that we want to be at. It is worth mentioning that branches are nothing but "labels". They just point to a commit in the tree. So if we can make the branch label point to that place in the commit tree, we have restored our branch as it was before deletion.&lt;/p&gt;

&lt;p&gt;To do that, first, we recreate our lost branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git checkout -b feature_1
Switched to a new branch 'feature_1'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically we are recreating the label. But now it is pointing to the wrong commit. At the moment it is pointing to the &lt;br&gt;
same commit as &lt;code&gt;main&lt;/code&gt;.  In our new branch, we use the &lt;code&gt;reset&lt;/code&gt; command with the &lt;code&gt;--hard&lt;/code&gt; flag to set the branch tip to &lt;code&gt;ef640e4 HEAD@{1}: commit: Add settings flag for feature_1&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(feature_1) $ git reset --hard ef640e4
HEAD is now at ef640e4 Add settings flag for feature_1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if we look at the Git log, we can see that our branch is restored:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* ef640e4 (HEAD -&amp;gt; feature_1) Add settings flag for feature_1
* 4015b6f (main) Provide default for product size
* d8dc31c Add db info to settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example we only had one commit in the branch, so we pointed to that. If you had more commits in your lost branch,&lt;br&gt;
the process is exactly the same. Just point to the last commit in the lost branch, and you are good to go.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chipper-musician-9131.ck.page/3b59da746f"&gt;&lt;br&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v5jqNtBm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7p0tvmpoif5752rqp4bc.png" alt="signup" width="660" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Accidentally committed to the wrong branch? Here is how to fix it.</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Wed, 02 Feb 2022 05:35:04 +0000</pubDate>
      <link>https://dev.to/foadlind/accidentally-committed-to-the-wrong-branch-here-is-how-to-fix-it-29lg</link>
      <guid>https://dev.to/foadlind/accidentally-committed-to-the-wrong-branch-here-is-how-to-fix-it-29lg</guid>
      <description>&lt;p&gt;If you have made a commit to the wrong branch, there is nothing to worry about. You can easily move the commit to the&lt;br&gt;
correct branch. Let me show you how with an example:&lt;/p&gt;

&lt;p&gt;Let's say I made a commit to the &lt;code&gt;main&lt;/code&gt; branch that was meant to be in the &lt;code&gt;feature_1&lt;/code&gt; branch (commit &lt;code&gt;55f0c29&lt;/code&gt; shown below).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* 55f0c29 (HEAD -&amp;gt; main) Add settings flag for feature_1
* 4015b6f Provide default for product size
* d8dc31c Add db info to settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want to undo that last commit and keep the changes. To do that, we use the &lt;code&gt;reset&lt;/code&gt; command with the &lt;code&gt;--soft&lt;/code&gt; flag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(main)$ git reset --soft HEAD^ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;HEAD^&lt;/code&gt; means the commit before where &lt;code&gt;HEAD&lt;/code&gt; is now. In our case &lt;code&gt;4015b6f&lt;/code&gt;. We use &lt;code&gt;--soft&lt;/code&gt; so that Git preserves our&lt;br&gt;
changes. If we look at Git status we will see that our change is still there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(main)$ git status
On branch main
Changes to be committed:
  (use "git restore --staged &amp;lt;file&amp;gt;..." to unstage)
    modified:   file.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can check out the destination branch and make our commit there. In my case &lt;code&gt;feature_1&lt;/code&gt; branch didn't exist, &lt;br&gt;
so I am creating it here with the &lt;code&gt;-b&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(main)$ git checkout -b feature_1
Switched to a new branch 'feature_1'

(feature_1)$ git status
On branch feature_1
Changes to be committed:
  (use "git restore --staged &amp;lt;file&amp;gt;..." to unstage)
    modified:   file.txt

(feature_1)$ git commit -m "Add settings flag for feature_1"
[feature_1 ef640e4] Add settings flag for feature_1
 1 file changed, 1 insertion(+) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I look at my &lt;a href="https://practicalgit.com/blog/create-a-good-looking-git-commit-tree-in-terminal.html"&gt;Git log&lt;/a&gt; I see that &lt;code&gt;HEAD&lt;/code&gt; is pointing to the new commit in the new branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* ef640e4 (HEAD -&amp;gt; feature_1) Add settings flag for feature_1
* 4015b6f (main) Provide default for product size.
* d8dc31c Add db info to settings.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://chipper-musician-9131.ck.page/fc2d4720ba"&gt;&lt;br&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mAEEM7mp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97ydrey0skt5rq5gbht6.png" alt="signup" width="675" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>git</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Undo a merge or a rebase</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Fri, 28 Jan 2022 07:32:46 +0000</pubDate>
      <link>https://dev.to/foadlind/undo-a-merge-or-a-rebase-2o2d</link>
      <guid>https://dev.to/foadlind/undo-a-merge-or-a-rebase-2o2d</guid>
      <description>&lt;p&gt;Have you merged the wrong branch into your branch? or maybe you rebased your branch on the main branch but something &lt;br&gt;
went wrong during the process? Don't worry! You can undo a merge/rebase process fairly easily.&lt;/p&gt;

&lt;p&gt;Before doing a dangerous operation, like merging or rebasing, Git saves your previous &lt;code&gt;HEAD&lt;/code&gt; location in a special &lt;br&gt;
variable called &lt;code&gt;ORIG_HEAD&lt;/code&gt;. This way you can always go back to where &lt;code&gt;HEAD&lt;/code&gt; was before you started the operation.&lt;/p&gt;

&lt;p&gt;Let's say I have a branch called &lt;code&gt;feature_1&lt;/code&gt;. I have accidentally merged the wrong branch into it. Instead of merging&lt;br&gt;
&lt;code&gt;main&lt;/code&gt;, I merged &lt;code&gt;develop&lt;/code&gt; to it (commit &lt;code&gt;af735d2&lt;/code&gt;). I would like to undo this operation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*   af735d2 (HEAD -&amp;gt; feature_1) Merge branch 'develop' into feature_1
|\
| * db7d7a6 (develop) add login button
| * 2f0ae72 (main) add test fixtures
* | 2d487f5 create user profile page
|/
* 2f591bd fix bug #1
* 290fc8b add db config file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before I did the merge, Git saved the value of the previous HEAD location to the &lt;code&gt;ORIG_HEAD&lt;/code&gt; variable. In this case,&lt;br&gt;
&lt;code&gt;2d487f5&lt;/code&gt;.&lt;br&gt;
To remove the last commit I can instruct Git to reset to the location of &lt;code&gt;ORIG_HEAD&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(feature_1)$ git reset --hard ORIG_HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now my commit tree is clean, and I am back to where I was before the wrong merge. &lt;br&gt;
Notice that the merge commit is removed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* db7d7a6 (develop) add login button
* 2f0ae72 (main) add test fixtures
| * 2d487f5 (HEAD -&amp;gt; feature_1) create user profile page
|/
* 2f591bd fix bug #1
* 290fc8b add db config file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use the same command for undoing a rebase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chipper-musician-9131.ck.page/fc2d4720ba"&gt;&lt;br&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mAEEM7mp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97ydrey0skt5rq5gbht6.png" alt="signup" width="675" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Best place to put queries in a Django project? Model Managers!</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Tue, 13 Jul 2021 09:09:50 +0000</pubDate>
      <link>https://dev.to/foadlind/best-place-to-put-queries-in-a-django-project-model-managers-3jbh</link>
      <guid>https://dev.to/foadlind/best-place-to-put-queries-in-a-django-project-model-managers-3jbh</guid>
      <description>&lt;p&gt;A question often arises when Django projects start to grow: "Where to put all the queries?"&lt;/p&gt;

&lt;p&gt;When it comes to this question, a good concept to have in mind is &lt;strong&gt;fat models and thin views&lt;/strong&gt;. This means that, as much as possible, you should try to keep business logic out of views and closer to your models.&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://docs.djangoproject.com/en/dev/topics/db/models/#model-methods"&gt;Djagno documentation&lt;/a&gt;, you should:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Define custom methods on a model to add custom “row-level” functionality to your objects. Whereas Manager methods &lt;br&gt;
are intended to do “table-wide” things, model methods should act on a particular model instance. &lt;br&gt;
This is a valuable technique for keeping business logic in one place – the model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Queries on a model can be considered "table-wide" logic, so a good place for them is in the model Manager methods. &lt;/p&gt;

&lt;p&gt;Here is an example to illustrate this point:&lt;/p&gt;

&lt;p&gt;Let's say you have a model called Membership in your project. A Membership is connected to a User and an Organization. Now, in one of your views you want to present all the memberships a user has. You could do it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# models.py
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Membership&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;organization&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Organization&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# views.py
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_memberships&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;memberships&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Membership&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'myapp/my_memberships.html'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'memberships'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;memberships&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is all good and dandy, but what if you want to make another view that needs to retrieve all the user's memberships? Then you would need to copy the memberships query to the new view. You would be duplicating code! &lt;/p&gt;

&lt;p&gt;A better way is to move this query to the Membership model manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#models.py
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MembershipManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_memberships_for_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Membership&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;organization&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Organization&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;objects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MembershipManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;#views.py
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_memberships&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;memberships&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Membership&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_memberships_for_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'myapp/my_memberships.html'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'memberships'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;memberships&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, we can reuse the query logic in other places and avoid duplication. Views that use this method will be more readable and self-documenting. Another added benefit is that you can test this query separately without needing to test the entire view.&lt;/p&gt;

&lt;p&gt;You can read more about model managers &lt;a href="https://docs.djangoproject.com/en/dev/topics/db/managers/"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>django</category>
    </item>
    <item>
      <title>All you need to know to survive in Git!</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Thu, 08 Jul 2021 08:12:51 +0000</pubDate>
      <link>https://dev.to/foadlind/all-you-need-to-know-to-survive-in-git-4hoo</link>
      <guid>https://dev.to/foadlind/all-you-need-to-know-to-survive-in-git-4hoo</guid>
      <description>&lt;p&gt;&lt;small&gt;* Photo by &lt;a href="https://unsplash.com/@milandegraeve?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;milan degraeve&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;small&gt;&lt;/small&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Learning Git can be really overwhelming. There are a lot of new concepts to learn and there are a lot of commands that you need to memorize. Every time you think you know what you are doing, Git throws a new challenge at you and makes you humble.&lt;/p&gt;

&lt;p&gt;Of course when you are a Git beginner this happens more often. It can be demotivating and frustrating. &lt;/p&gt;

&lt;p&gt;I am here to tell you that you don't need to beat yourself up about it. Even seasoned Git users need to look up commands now and then.&lt;/p&gt;

&lt;p&gt;In the beginning you just need to survive. You need to know just enough Git to get by. Just enough so that it gets out of your way, and lets you focus on other activities like coding, building, shipping, etc. &lt;/p&gt;

&lt;p&gt;You need some basic Git survival skills!&lt;/p&gt;

&lt;h2&gt;
  
  
  So what are these Git survival skills?
&lt;/h2&gt;

&lt;p&gt;To survive, there are a subset of Git concepts that you need to understand, and a handful of commands to remember:&lt;/p&gt;

&lt;h3&gt;
  
  
  Skill 1: Initializing and cloning repositories
&lt;/h3&gt;

&lt;p&gt;Git repositories are not magic. They are just a folder of files with a &lt;code&gt;.git&lt;/code&gt; folder inside. Go ahead and list all the files (and hidden files) in a Git repository. You will see a &lt;code&gt;.git&lt;/code&gt; folder in there. In that folder, Git keeps a record of the commits that have been made, who made them, when, and so on.&lt;/p&gt;

&lt;p&gt;When you initialize a repository using &lt;code&gt;git init&lt;/code&gt; inside a folder, you create the &lt;code&gt;.git&lt;/code&gt; folder there for the first time. From then on, Git will track everything that happens in your repository.&lt;/p&gt;

&lt;p&gt;When you clone a repository, you are basically downloading a folder that includes the project files but also a &lt;code&gt;.git&lt;/code&gt; folder. Git will set up things so that you can communicate with where you cloned from (for example GitHub) so that later you can send your changes to it (push) or update from it (pull). To clone a repository you need to provide the URL for that repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone [URL]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Skill 2: Checking the status of your local changes
&lt;/h3&gt;

&lt;p&gt;You should be able to get an overview of your local changes in Git at any time. This is useful just before you commit or if you just want to remember what files you have changed. You can easily do that using the status command in your repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git status

On branch feature_1
Changes not staged for commit:
  (use "git add &amp;lt;file&amp;gt;..." to update what will be committed)
  (use "git restore &amp;lt;file&amp;gt;..." to discard changes in working directory)
    modified:   file.txt

Untracked files:
  (use "git add &amp;lt;file&amp;gt;..." to include in what will be committed)
    file2.txt

no changes added to commit (use "git add" and/or "git commit -a")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you can see that we are inside a branch called &lt;code&gt;feature_1&lt;/code&gt;. We have modified a file called &lt;code&gt;file.txt&lt;/code&gt; and there is a new file (&lt;code&gt;file2.txt&lt;/code&gt;) that is not added to Git yet and therefore it is reported as "Untracked".&lt;/p&gt;

&lt;p&gt;Now if you want to know what are the changes in &lt;code&gt;file.txt&lt;/code&gt;, you can use the diff command like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git diff file.txt

diff --git a/file.txt b/file.txt
index be05e9c..163b853 100644
--- a/file.txt
+++ b/file.txt
@@ -1,3 +1,3 @@
 Something
 Something more
-
+Something else
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that's a bit cryptic. I personally don't like it. To get an easy-to-understand diff, I suggest you use the Git integration in your favorite text editor or IDE. Here is an &lt;a href="https://www.roboleary.net/vscode/2020/09/15/vscode-git.html"&gt;excellent article&lt;/a&gt; describing how to set up VSCode so that it opens from terminal and shows you a good-looking diff.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skill 3: Staging and Committing
&lt;/h3&gt;

&lt;p&gt;The difference between the two, and the fact that there are two steps to committing, is sometimes confusing for Git beginners.  I wrote &lt;a href="https://practicalgit.com/blog/staging-vs-commit.html"&gt;an article&lt;/a&gt; about what the differences are and how you can use staging and committing to your advantage. Give it a read.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skill 4: Checking the history
&lt;/h3&gt;

&lt;p&gt;Another thing you need is the ability to find things in the repository history. Git history is basically a log of all the things that has happened in the repository.&lt;/p&gt;

&lt;p&gt;Most Git GUIs (and Git integrations in text editors and IDEs) offer a visual and intuitive presentation of this log in a form of a tree. You can see the branches, commits, tags, changed files, diffs, etc.&lt;/p&gt;

&lt;p&gt;Although you can definitely investigate the Git history in a terminal using the commands below, a Git GUI offers a more &lt;br&gt;
intuitive experience when it comes to investigating the history. I usually recommend &lt;a href="https://practicalgit.com/blog/learn-git-gui-or-command-line.html"&gt;learning Git in a terminal first&lt;/a&gt; before going to GUIs, &lt;br&gt;
but from this particular aspect, GUIs are better.&lt;/p&gt;

&lt;p&gt;If you choose to remain in the terminal, the &lt;code&gt;git log&lt;/code&gt; command is your friend. Although the default output is not so helpful, you can create a good-looking visualization of the log using some additional command arguments. You can even create an alias, so you don't need to write those command arguments each time. Read &lt;a href="https://practicalgit.com/blog/create-a-good-looking-git-commit-tree-in-terminal.html"&gt;this article&lt;/a&gt; to learn how to do it.&lt;/p&gt;

&lt;p&gt;You can show the contents of any commit using the commit hash. That's the crazy (but unique) number in front of each commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git show &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or you can jump to that commit by checking it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git checkout &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't get scared by the somewhat morbid message from git about a detached HEAD. You can switch back to where you were before, using &lt;code&gt;git switch -&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skill 5: Branching
&lt;/h3&gt;

&lt;p&gt;Branches are one of the most useful concepts in Git. Let's say you want to experiment on your code, for example refactor something or introduce a new feature. You would typically do this in a branch. That way you don't touch the code that already works. When you are satisfied with your results, you can merge your experiment branch to the main branch.&lt;/p&gt;

&lt;p&gt;You can create a new branch with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git branch [branch-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can move to another branch using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git checkout [branch-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Skill 6: Merging and resolving merge conflicts
&lt;/h3&gt;

&lt;p&gt;You also need to learn how to merge branches. Merging often seems scary to beginners because they are afraid they will write over other people's work or that they will get&lt;br&gt;
a merge conflict.&lt;/p&gt;

&lt;p&gt;To prevent writing over other people's work, always make sure that the branch you are merging into is updated. Check out the destination branch and do a pull before you merge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git pull
Already up to date.

$ git merge [your-branch-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes you end up in a merge conflict state. It's just the reality of working with Git. There is no need to panic. &lt;br&gt;
Just follow &lt;a href="https://practicalgit.com/blog/resolve-merge-conflicts.html"&gt;this guide&lt;/a&gt;, and you will become a Git conflict resolution guru.&lt;/p&gt;
&lt;h3&gt;
  
  
  Skill 7: Syncing with a remote
&lt;/h3&gt;

&lt;p&gt;Sooner or later you will need to put your project on GitHub (or GitLab, or BitBucket, etc). Or you might need to collaborate with others on the same repository.&lt;br&gt;
So you need to send your changes to a remote repository, and download changes from it. This is when push, pull and fetch come into the picture.&lt;/p&gt;

&lt;p&gt;Push is pretty obvious. &lt;code&gt;git push&lt;/code&gt; simply sends commits you have done locally in your current branch up to the remote repository. However, if this is the first time you are&lt;br&gt;
pushing a new branch to remote, you need to use a slightly different command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push -u origin my_new_branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember, this is done only if you have just created &lt;code&gt;my_new_branch&lt;/code&gt; and this is the first time you are pushing it to the remote repository.  Read more about this &lt;a href="https://practicalgit.com/blog/do-you-always-need-u-in-push.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before we get to pull, we need to talk about fetch. &lt;code&gt;git fetch&lt;/code&gt; asks the remote about the latest developments. It doesn't change your files. It just downloads the history from remote so that you can visualize what has happened on the remote since the last time you synced.&lt;/p&gt;

&lt;p&gt;Pull is like fetch except that it will not only update history, it will also merge the changes from remote to your local files. If you have changed some file and &lt;br&gt;
another colleague has changed the same file and pushed it, you will get a merge conflict on that file if you do a pull. This is not bad. It's just Git asking you for guidance on how to merge these changes. You can follow my &lt;a href="https://practicalgit.com/blog/resolve-merge-conflicts.html"&gt;merge conflict resolution guide&lt;/a&gt; to resolve it.&lt;/p&gt;

&lt;p&gt;One important rule is to always do a pull before you push your changes. This way if there is a conflict, you get a chance to solve it locally and do not risk overwriting other people's work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond survival
&lt;/h2&gt;

&lt;p&gt;Now you are equipped with all the survival skills you need to use Git on a day-to-day basis. My guess is that this list helps you in about 90% of your work with Git.&lt;br&gt;
There are of course more things to learn. For example, when you are comfortable with these basic concepts, you might want to take a look at rebasing and cherry-picking.&lt;br&gt;
You don't need them right now, but they might come in handy one day.&lt;/p&gt;

&lt;p&gt;So to recap, you need to know how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;initialize and clone a repository,&lt;/li&gt;
&lt;li&gt;check the status of your work,&lt;/li&gt;
&lt;li&gt;stage and commit your changes,&lt;/li&gt;
&lt;li&gt;check the history of the repository,&lt;/li&gt;
&lt;li&gt;make branches and jump between them,&lt;/li&gt;
&lt;li&gt;merge branches and resolve merge conflicts,&lt;/li&gt;
&lt;li&gt;sync with a remote using push and pull.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To help you remember all these commands, I have created a &lt;a href="https://chipper-musician-9131.ck.page/fc2d4720ba"&gt;cheat sheet that you download&lt;/a&gt;. Print it out and put it somewhere that is easy to see.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>git</category>
    </item>
    <item>
      <title>Staging vs. Committing: an explanation for Git beginners</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Wed, 17 Mar 2021 12:00:24 +0000</pubDate>
      <link>https://dev.to/foadlind/staging-vs-committing-an-explanation-for-git-beginners-2a5o</link>
      <guid>https://dev.to/foadlind/staging-vs-committing-an-explanation-for-git-beginners-2a5o</guid>
      <description>&lt;p&gt;I get these questions quite often:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is the difference between staging and committing?"&lt;/p&gt;

&lt;p&gt;"Why is there a &lt;code&gt;git add&lt;/code&gt; and a &lt;code&gt;git commit&lt;/code&gt;? What's the difference?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is the difference?
&lt;/h2&gt;

&lt;p&gt;Imagine you are doing online shopping. You browse through the pages of your favorite online store and add some products to your shopping cart. The shopping cart is like &lt;strong&gt;staging&lt;/strong&gt;. Things are there ready to be paid for. You can keep adding stuff to it or remove some from it. &lt;/p&gt;

&lt;p&gt;When you are done shopping, you go and pay for the things in your shopping cart. That can be compared to making a &lt;strong&gt;commit&lt;/strong&gt;. Now there is a record somewhere of what you have bought and when. There is a history.&lt;/p&gt;

&lt;p&gt;Notice that you can easily change your mind when things are in staging, but once you have made a commit things are hard to change (although not impossible!).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are they separated?
&lt;/h2&gt;

&lt;p&gt;The fact that you need to stage and commit separately in Git has many benefits. Generally it is a good idea to make your commits small. And to make sure that all the changes that are included in one commit are related to each other. &lt;/p&gt;

&lt;p&gt;For example a commit that fixes a bug in Feature A should not also include an improvement you made to Feature B. If you have been productive 😎 and have done those two things at once, you should not commit everything at once. You should separate them by staging the bug fixes and committing those first and then staging the improvements to Feature B and making a second commit. &lt;/p&gt;

&lt;p&gt;That way, if someone looks at the Git history of your project, they are not confused by one giant commit that did a lot of things. They can see clearly that you performed two different tasks: one bug fix in Feature A and one improvement to Feature B.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to stage and commit
&lt;/h2&gt;

&lt;p&gt;Ok so now that you know the difference between &lt;strong&gt;staging&lt;/strong&gt; and &lt;strong&gt;committing&lt;/strong&gt;, let's see how to do these things in Git:&lt;/p&gt;

&lt;p&gt;To &lt;strong&gt;add&lt;/strong&gt; the changes you made to a file to staging, use this command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git add &amp;lt;path-to-file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to add all the files at once, put a dot instead of path to each file, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the changes will be staged, ready to be committed.&lt;/p&gt;

&lt;p&gt;To commit use the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"some descriptive message"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have created a Git cheat sheet for beginners to make it easier to look up these basic commands. You can grab a free copy from &lt;a href="https://chipper-musician-9131.ck.page/fc2d4720ba"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Git vs. GitHub: an explanation for absolute beginners</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Tue, 16 Mar 2021 09:21:58 +0000</pubDate>
      <link>https://dev.to/foadlind/git-vs-github-an-explanation-for-absolute-beginners-1kb8</link>
      <guid>https://dev.to/foadlind/git-vs-github-an-explanation-for-absolute-beginners-1kb8</guid>
      <description>&lt;p&gt;This is a question a lot of Git beginners have:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is the difference between Git and GitHub?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It can be confusing to understand their difference when you first encounter these new concepts. In this article I will try to give you some context for how Git and GitHub are related and what that means to you.&lt;/p&gt;

&lt;p&gt;Git is the version control software you can use locally on your machine to keep track of changes you make to your projects. Git is an open-source project itself that was made by the team developing Linux operating system to keep track of the changes to their code. There are other version control software beside Git (Subversion, Mercurial, etc), but Git is by far the most common and most powerful.&lt;/p&gt;

&lt;p&gt;GitHub is a web service that allows you to store your projects in the cloud using Git. You don't need GitHub to be able to use Git. But if you want to back up your projects in the cloud or share it with others, you can use GitHub.&lt;/p&gt;

&lt;p&gt;GitHub is not the only option though. There are at least two other major ones: GitLab and Bitbucket.&lt;/p&gt;

&lt;p&gt;Apart from storing your project files and your project's Git history, these services provide other tools that are useful for collaborating with others. Things like code review tools, project management tools, team communication tools, bug tracking, etc.&lt;/p&gt;

&lt;p&gt;Sooner or later you will need to collaborate with others on a project. Usually you will do that by uploading your code (&lt;strong&gt;push&lt;/strong&gt;ing it) to GitHub. Then others can download (&lt;strong&gt;clone&lt;/strong&gt;) your code and start working on it. When they have made some changes and want to share it with you, they &lt;strong&gt;push&lt;/strong&gt; it up to GitHub. Then you can &lt;strong&gt;pull&lt;/strong&gt; the changes down to your local Git and see what they have done. This is the ground of all collaboration done on GitHub and is the central workflow for all Git projects. &lt;/p&gt;

&lt;p&gt;In order for Git to send your project to GitHub, you need to give your project a &lt;strong&gt;remote&lt;/strong&gt; address. You can go to GitHub and create a home for your project, called a &lt;strong&gt;repository&lt;/strong&gt;. Then you give the address of that repository to Git. After that you are able to just push your files to its new remote home on GitHub.&lt;/p&gt;

&lt;p&gt;You can also download other people's work from GitHub. This process is called &lt;strong&gt;clone&lt;/strong&gt;ing. You clone a repository like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone &amp;lt;address-of-the-repository&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the address of the repository from it's GitHub page. It usually looks something like this: &lt;code&gt;git@github.com:username/some-cool-project-name.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So in summary, Git is a version control system and GitHub is a web service that helps you collaborate with others using Git.&lt;br&gt;
I hope this article helped to clear some of the confusion around Git and GitHub! 🙂&lt;br&gt;
I have also created a Git cheat sheet for beginners. If you are interested, grab a free copy from &lt;a href="https://chipper-musician-9131.ck.page/fc2d4720ba"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Authentication with Django REST Framework</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Fri, 26 Feb 2021 06:04:14 +0000</pubDate>
      <link>https://dev.to/foadlind/authentication-with-django-rest-framework-2caf</link>
      <guid>https://dev.to/foadlind/authentication-with-django-rest-framework-2caf</guid>
      <description>&lt;p&gt;In this post I will go through some common authentication mechanisms that are used with Django REST Framework (DRF). Some of these methods are included in DRF, and the others are custom authentication packages that implement popular schemes not included in DRF. We will go through how each scheme works and when it should be used. I have also included some resources for learning how to implement each. &lt;/p&gt;

&lt;p&gt;But before we dig in, we need to look at how authentication works in DRF.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication in Django REST Framework
&lt;/h2&gt;

&lt;p&gt;Authentication is a way for your service to determine whether the user is who they claim to be. When that is determined, your service can check whether they are allowed to access certain information.&lt;/p&gt;

&lt;p&gt;In DRF, authentication is the first check that happens upon receiving a request. All other checks (like permissions, throttling, etc) are done afterwards. You can have several ways of authenticating users for the same API service, each used for a different type of client. &lt;br&gt;
You can set your API's authentication schemes globally in your setting file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# settings.py
&lt;/span&gt;&lt;span class="n"&gt;REST_FRAMEWORK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DEFAULT_AUTHENTICATION_CLASSES&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rest_framework.authentication.BasicAuthentication&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rest_framework.authentication.SessionAuthentication&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case DRF will first try the &lt;code&gt;BasicAuthentication&lt;/code&gt; scheme for each request. If that fails, it will try the next authentication scheme in the list and so on.&lt;/p&gt;

&lt;p&gt;You can also override these global settings for each view individually. For example this view will only allow requests that use the &lt;code&gt;TokenAuthentication&lt;/code&gt; scheme:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeSpecialView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;APIView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;authentication_classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TokenAuthentication&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do choose to have specific authentication schemes for specific views make sure you always have a global one set in your settings file to fall back on.&lt;/p&gt;

&lt;h2&gt;
  
  
  A tour of common authentication schemes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  BasicAuthentication
&lt;/h3&gt;

&lt;p&gt;This is the most ... uh ... basic authentication scheme you can have. Users identify themselves with a username and password. This is also the least secure scheme. Users will be sending their precious passwords over the wire. Only use it in testing. If you absolutely must use it, make sure your API is only available over HTTPS.&lt;/p&gt;

&lt;p&gt;You can implement it by just importing it from DRF and adding it to to a specific view or to your &lt;code&gt;settings.py&lt;/code&gt; as a default authentication class.&lt;/p&gt;

&lt;p&gt;Users then send requests to the API and include HTTP Basic Authentication header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GET https://example.com/api/books/123/
Authorization: Basic myusername mypasswd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  TokenAuthentication
&lt;/h3&gt;

&lt;p&gt;In this scheme you give each user a unique token and they include it in every request they make. This is appropriate for client-serer applications, for example for desktop or mobile apps that need to access your API. Note that anyone that gets hold of the token can use it and authenticate themselves as a user.&lt;/p&gt;

&lt;p&gt;To implement TokenAuthentication you need to add &lt;code&gt;rest_framework.authtoken&lt;/code&gt; to the list of &lt;code&gt;INSTALLED_APPS&lt;/code&gt; in your &lt;code&gt;settings.py&lt;/code&gt; file. This app takes care of creation, validation and management of user tokens in your database. Therefore you need to run migrations after you add it so that it can create token management tables in the database. Then you need to a way to create token for each user and give it to them. For example in your web app you can make a page where logged in users can see their token. You create tokens for your users like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# views.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rest_framework.authtoken.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Token&lt;/span&gt;

&lt;span class="nd"&gt;@login_required&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;user_token_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;myapp/user_token.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should provide a way for users to generate a new token (and therefore revoke the old one) in case they feel like the token has been compromised. &lt;/p&gt;

&lt;p&gt;Your users then can send requests to your API and authenticate themselves by adding the token to the Authorization HTTP header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GET https://example.com/api/books/123/
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SessionAuthentication
&lt;/h3&gt;

&lt;p&gt;This scheme is particularly good for Single Page Applications where the user logs in to your app, creates a session in Django and then the app sends AJAX requests to the server to fill the page with relevant information.&lt;br&gt;
This scheme works based on Django's session framework so make sure it is included in &lt;code&gt;INSTALLED_APPS&lt;/code&gt; in your &lt;code&gt;settings.py&lt;/code&gt; files. Read more about Django sessions &lt;a href="https://docs.djangoproject.com/en/dev/topics/http/sessions/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Django has excellent documentation on how to securely make &lt;a href="https://docs.djangoproject.com/en/dev/ref/csrf/#ajax" rel="noopener noreferrer"&gt;AJAX calls using Django sessions&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  OAuth2
&lt;/h3&gt;

&lt;p&gt;OAuth2 is a popular standard for authentication. It provides guidelines for user authentication as well as authenticating third-party apps on behalf of the user. &lt;a href="https://aaronparecki.com/oauth-2-simplified/" rel="noopener noreferrer"&gt;Here&lt;/a&gt; and &lt;a href="https://medium.com/@darutk/diagrams-and-movies-of-all-the-oauth-2-0-flows-194f3c3ade85" rel="noopener noreferrer"&gt;here&lt;/a&gt; you can read more about details of each authentication "flow" and their appropriate use cases.&lt;/p&gt;

&lt;p&gt;You can find the technical standard specification &lt;a href="https://tools.ietf.org/html/rfc6749" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Thankfully you don't need to implement this giant standard yourself. You can use the excellent &lt;a href="https://github.com/jazzband/django-oauth-toolkit" rel="noopener noreferrer"&gt;Django OAuth Toolkit package&lt;/a&gt;. They also have a specific section in their documentation for &lt;a href="https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/rest-framework.html" rel="noopener noreferrer"&gt;using it with DRF&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON Web Token (JWT) Authentication
&lt;/h3&gt;

&lt;p&gt;This is a new and popular standard that works similar to TokenAuthentication except that it does not need to save tokens in the database. Your app generates JWTs that are signed using a secret. Then you give this token to the user to include in their request just as in TokenAuthentication. &lt;/p&gt;

&lt;p&gt;Every time you receive the token, you decode it and check its signature. If it's valid you know that it has not been tampered with. The token is actually nothing but a json string that includes some claims. These claims can be the username, token expiry date, etc. You can read more about the details of the token &lt;a href="https://jwt.io/introduction/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For JWT authentication you can use the &lt;a href="https://django-rest-framework-simplejwt.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Simple JWT&lt;/a&gt; package that implements it for DRF.&lt;/p&gt;

&lt;h2&gt;
  
  
  A word on Security
&lt;/h2&gt;

&lt;p&gt;I hope this guide has given you a good overview of the most common authentication schemes to use with Django REST Framework. Be aware that no authentication scheme is perfect from the security perspective. Make sure you do extensive research before choosing an authentication scheme and always follow best practices provided by Django and DRF documentations. You are not only responsible for the security of your app, you are also responsible for the security of your users and their data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chipper-musician-9131.ck.page/71c2932d23" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frx6dciscpdwtk3z6j4u6.png" alt="signup"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>djangorestframework</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Creating custom manage.py commands for Django</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Sat, 10 Oct 2020 17:40:27 +0000</pubDate>
      <link>https://dev.to/foadlind/creating-custom-manage-py-commands-for-django-33cc</link>
      <guid>https://dev.to/foadlind/creating-custom-manage-py-commands-for-django-33cc</guid>
      <description>&lt;p&gt;For my recent project &lt;a href="https://www.pyremote.com" rel="noopener noreferrer"&gt;&lt;strong&gt;pyremote&lt;/strong&gt;&lt;/a&gt;, I needed to run a script every night to remove old job postings from the database. I decided to implement it as a &lt;strong&gt;custom manage.py&lt;/strong&gt; command so that I can easily run it from the command line and add it to a nightly cron job on the server.&lt;/p&gt;

&lt;p&gt;To create a custom command you need to add a &lt;code&gt;management&lt;/code&gt; directory to your Django app. In there create another directory called &lt;code&gt;commands&lt;/code&gt; and in that one add a Python file and call it the way you want the command to be called. In my case I called it &lt;code&gt;purge_old_jobs.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pyremote/
    __init__.py
    management/
        commands/
            purge_old_jobs.py
    models.py
    views.py
    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Python file you create must define a class called &lt;code&gt;Command&lt;/code&gt; that inherits from &lt;code&gt;BaseCommand&lt;/code&gt;. Create a method named &lt;code&gt;handle&lt;/code&gt; in your &lt;code&gt;Command&lt;/code&gt; class. The actual logic of the command goes in this method. &lt;/p&gt;

&lt;p&gt;You can also define &lt;code&gt;add_argument&lt;/code&gt; method where you specify any command line arguments you would like to pass to the custom command when you invoke it. These arguments are then available to the &lt;code&gt;handle&lt;/code&gt; method in a dictionary called &lt;code&gt;options&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# purge_old_jobs.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.core.management.base&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseCommand&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pyremote.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Job&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseCommand&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Cleans database from job posts older than the given number of days.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_arguments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;days&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Retention period in days.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;retention_period&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;days&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;expiry_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;retention_period&lt;/span&gt;
        &lt;span class="n"&gt;number_deleted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Job&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creation_date__lt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;expiry_date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Number of expired jobs: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;number_deleted&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I can run this command to clean the database from jobs that are added to the page more than 30 days ago:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python manage.py purge_old_jobs 30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://chipper-musician-9131.ck.page/71c2932d23" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frx6dciscpdwtk3z6j4u6.png" alt="signup"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
    </item>
    <item>
      <title>Dockerizing a Django + MySQL project</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Mon, 05 Oct 2020 13:52:22 +0000</pubDate>
      <link>https://dev.to/foadlind/dockerizing-a-django-mysql-project-g4m</link>
      <guid>https://dev.to/foadlind/dockerizing-a-django-mysql-project-g4m</guid>
      <description>&lt;p&gt;If you are here, I assume you have already embraced the merits of using Docker to set up your development environment such that it matches your staging and production environments. &lt;/p&gt;

&lt;p&gt;In this guide I show you how to run your Django app in one Docker container and your MySQL database in another and make them talk to each other.&lt;/p&gt;

&lt;p&gt;We are going to manage and run these two containers using &lt;a href="https://docs.Docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;👉 If you want to learn how to do this for a Django + Postgres app read &lt;a href="https://foadmoha.com/blog/dockerize-django-postgres-project.html" rel="noopener noreferrer"&gt;this post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am assuming you already have a Django project locally that is using a local database and that your project has a &lt;code&gt;requirements.txt&lt;/code&gt; file. You should also &lt;a href="https://docs.Docker.com/get-Docker/" rel="noopener noreferrer"&gt;install Docker on your machine&lt;/a&gt; if you haven't already.&lt;/p&gt;

&lt;p&gt;Let's dive right in:&lt;/p&gt;

&lt;p&gt;The first step is to create a &lt;code&gt;Dockerfile&lt;/code&gt; in the root of your project (this is where you have your &lt;code&gt;requirements.txt&lt;/code&gt; and &lt;code&gt;manage.py&lt;/code&gt; files).&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 Dockerfile
FROM python:3.8
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's go through that line by line:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FROM python:3.8&lt;/code&gt; is the base image your Docker image will be built upon. This will be pulled from DockerHub.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ENV PYTHONUNBUFFERED 1&lt;/code&gt; ensures that the output Django writes to the terminal comes out in real time without being buffered somewhere. This makes your Docker logs useful and complete.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WORKDIR /app&lt;/code&gt; creates a new folder in your container called &lt;code&gt;app&lt;/code&gt; which will be your project's root inside the container. It then sets that as the work directory in which the subsequent commands will be executed in.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COPY requirements.txt /app/requirements.txt&lt;/code&gt; copies your local &lt;code&gt;requirements.txt&lt;/code&gt; file to the Docker container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RUN pip install -r requirements.txt&lt;/code&gt; will make sure you have all your project dependencies installed inside the container.&lt;/li&gt;
&lt;li&gt; &lt;code&gt;COPY . /app&lt;/code&gt; and finally it's time to copy your project's content into the Docker container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now create a new file in your local project root. This one is called &lt;code&gt;docker-compose.yml&lt;/code&gt; and is used for configuring Docker Compose.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 yml
version: '3'
services:
  db:
    image: mysql:8
    ports:
      - "3306:3306"
    environment:
      - MYSQL_DATABASE='mydatabase'
      - MYSQL_USER='root'
      - MYSQL_PASSWORD='some_password'
      - MYSQL_ROOT_PASSWORD='some_password'
      - MYSQL_HOST=''
    volumes:
      - /tmp/app/mysqld:/var/run/mysqld
      - ./db:/var/lib/mysql
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    ports:
      - "8000:8000"
    volumes:
      - .:/app
      - /tmp/app/mysqld:/run/mysqld
    depends_on:
      - db


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This defines two services: &lt;strong&gt;db&lt;/strong&gt; and &lt;strong&gt;web&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;db&lt;/strong&gt; uses an official MySQL image from DockerHub. We attach local port 3306 to port 3306 of this container. We then set a bunch of environment variables that are required for MySQL. Make sure you also set these in your Django database settings. (You can put these in a &lt;code&gt;.env&lt;/code&gt; file to avoid committing sensitive information to version control. Read &lt;a href="https://docs.docker.com/compose/compose-file/#env_file" rel="noopener noreferrer"&gt;here&lt;/a&gt; to learn how.) &lt;/p&gt;

&lt;p&gt;&lt;code&gt;volume&lt;/code&gt; define two volume mappings: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first one maps the contents of &lt;code&gt;var/run/mysqld&lt;/code&gt; of the container to a local folder on your machine. This file contains socket information that enables the &lt;strong&gt;web&lt;/strong&gt; service (your Django app) to talk to the database service. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;./db:/var/lib/mysql&lt;/code&gt; creates a local &lt;code&gt;db&lt;/code&gt; folder in your project root so that database information can be saved if you destroy the &lt;strong&gt;db&lt;/strong&gt; service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;web&lt;/strong&gt; build its image using the &lt;code&gt;Dockerfile&lt;/code&gt; we created earlier. It then runs the Django server and exposes port 8000 to your machine. We map your local project folder to the app folder and we bring in the socket file. We tell Docker Compose that this service is dependant on the &lt;strong&gt;db&lt;/strong&gt; service.&lt;/p&gt;

&lt;p&gt;Now all we have to do is to start everything up. In your project root run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 bash
$ docker-compose up


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This should build your images and start the containers. Open a browser and go to &lt;code&gt;0.0.0.0:8000&lt;/code&gt;. You should see your app. Now if you open a new terminal and run a &lt;code&gt;docker ps&lt;/code&gt; you will see the &lt;strong&gt;web&lt;/strong&gt; and &lt;strong&gt;db&lt;/strong&gt; containers are running:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 bash
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                        NAMES
77a320233bf2        my_project_web      "python manage.py ru…"   4 minutes ago       Up 4 minutes        0.0.0.0:8000-&amp;gt;8000/tcp       my_project_web_1
66324c20d91e        mysql:8             "docker-entrypoint.s…"   4 minutes ago       Up 4 minutes        0.0.0.0:3306-&amp;gt;3306/tcp       my_project_db_1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you want to stop Docker Compose, press &lt;em&gt;Ctrl+C&lt;/em&gt; in the first terminal or run &lt;code&gt;docker-compose stop&lt;/code&gt; in the project root folder in another terminal.&lt;/p&gt;

&lt;p&gt;To run &lt;code&gt;manage.py&lt;/code&gt; commands in the Django container (&lt;strong&gt;web&lt;/strong&gt;):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 bash
$ docker-compose run --rm web python manage.py migrate


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://chipper-musician-9131.ck.page/71c2932d23" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frx6dciscpdwtk3z6j4u6.png" alt="signup"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>docker</category>
    </item>
    <item>
      <title>Validating Django models that are created without forms</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Thu, 28 May 2020 17:33:33 +0000</pubDate>
      <link>https://dev.to/foadlind/validating-django-models-that-are-created-without-forms-29gp</link>
      <guid>https://dev.to/foadlind/validating-django-models-that-are-created-without-forms-29gp</guid>
      <description>&lt;p&gt;Usually instances of models (objects) are created using a &lt;code&gt;ModelForm&lt;/code&gt;. You know the drill: The user inputs some values in the form, hits submit and sends a &lt;code&gt;POST&lt;/code&gt; request with the data. In the view function/class, we do a model validation using &lt;code&gt;form.is_valid()&lt;/code&gt; and then save the object in the database. This gives a basic level of validation for the model fields. &lt;/p&gt;

&lt;p&gt;But what if we want to do a more comprehensive validation on the object? And what about a scenario where we want to create objects in some other way than using forms? Let's say through an API call. How do we validate the objects in that case?&lt;/p&gt;

&lt;p&gt;That is what &lt;strong&gt;validators&lt;/strong&gt; are for. Validators are callable functions that will check the object fields and raise &lt;code&gt;ValidationError&lt;/code&gt; if they contain values that don't meet our desired criteria. In case of &lt;code&gt;ModelForm&lt;/code&gt; the validation is done  when we call &lt;code&gt;form.is_valid()&lt;/code&gt;. Note that if we create an instance of the model ourselves, validators will not be run automatically. So we need to validate the objects first before saving them.&lt;/p&gt;

&lt;p&gt;Let's say we have a model called Person. Each person has a first name, a last name and an age. And for some reason, we don't want to save the person in our database if their age is less than 18. We can create a validator that checks for that. &lt;/p&gt;

&lt;p&gt;In &lt;code&gt;models.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.core.exceptions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ValidationError&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_age&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Age must be at least 18.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;validate_age&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now just before we save the object, we ask django to validate it by calling the &lt;code&gt;full_clean()&lt;/code&gt; method. &lt;/p&gt;

&lt;p&gt;In &lt;code&gt;views.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;myapp.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.core.exceptions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ValidationError&lt;/span&gt;

&lt;span class="c1"&gt;# let's create an object
&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;John&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last_name&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Doe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full_clean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Do something with the error here.
&lt;/span&gt;    &lt;span class="c1"&gt;# Maybe display to user or log it somewhere.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;person.full_clean()&lt;/code&gt; will run the relevant validators for all fields of the &lt;code&gt;person&lt;/code&gt; object. In this case it will run the &lt;code&gt;validate_age&lt;/code&gt; function on the &lt;code&gt;person.age&lt;/code&gt; field and throws an exception. This prevents this object from being saved. So young John will not be saved into the database! 🙂&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chipper-musician-9131.ck.page/71c2932d23" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frx6dciscpdwtk3z6j4u6.png" alt="signup"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Need to stash untracked files? There is a way!</title>
      <dc:creator>foadlind</dc:creator>
      <pubDate>Mon, 23 Mar 2020 14:29:07 +0000</pubDate>
      <link>https://dev.to/foadlind/need-to-stash-untracked-files-there-is-a-way-dhp</link>
      <guid>https://dev.to/foadlind/need-to-stash-untracked-files-there-is-a-way-dhp</guid>
      <description>&lt;p&gt;You are in the middle of some work. You have created a bunch of new files and edited some existing ones when your boss comes and tells you to deal with an emergency bug fix. You realize you need to switch branches but your work is incomplete and you don't want to commit it just yet.&lt;/p&gt;

&lt;p&gt;Stashing your changes is the best way to go. However, the default behavior of &lt;code&gt;git stash&lt;/code&gt; is to stash only the tracked files. The untracked files will remain in your repo. Sometimes that is ok. You can have them there while you switch branches and deal with the emergency. But, in some occasions, their existence might interfere with other things (like changing the behavior of the software, or getting accidentally added to a commit).&lt;/p&gt;

&lt;p&gt;I prefer to stash the untracked files every time I need to switch branches. That way I get a clean repo to work with. Less thinking required, and less room for error. It's the safest option.&lt;/p&gt;

&lt;p&gt;So how do you stash both tracked AND untracked files?&lt;/p&gt;

&lt;p&gt;Using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git stash &lt;span class="nt"&gt;--include-untracked&lt;/span&gt;
&lt;span class="c"&gt;# or the shorter alternative:&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git stash &lt;span class="nt"&gt;-u&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;"Will this include the files in my &lt;code&gt;.gitignore&lt;/code&gt;?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No. This will only include the untracked files you see when you do &lt;code&gt;git status&lt;/code&gt;. If you want to stash files included in &lt;code&gt;.gitignore&lt;/code&gt;, use &lt;code&gt;git stash --all&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I see what I have just stashed?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To see all tracked files you just stashed use &lt;code&gt;git show stash&lt;/code&gt;. To see all the untracked files you just stashed use &lt;code&gt;git show stash@{0}^3&lt;/code&gt;. Unfortunately there is no way, that I know of, to see both the tracked and untracked stashed files using one command. This is due to the way Git stores and applies stashed changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chipper-musician-9131.ck.page/562695812e"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---mEnIPdo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cufm58ypdt0dilhlgh5j.png" alt="signup" width="880" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
