<?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: Rasul Kireev</title>
    <description>The latest articles on DEV Community by Rasul Kireev (@rasulkireev).</description>
    <link>https://dev.to/rasulkireev</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%2F347535%2F298bd13b-4bbb-411c-9218-644f923049ee.jpeg</url>
      <title>DEV Community: Rasul Kireev</title>
      <link>https://dev.to/rasulkireev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rasulkireev"/>
    <language>en</language>
    <item>
      <title>Linux Laptops in 2025: A Developer's Guide to Hardware, Distros, and Making the Switch</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Mon, 23 Jun 2025 16:26:09 +0000</pubDate>
      <link>https://dev.to/rasulkireev/linux-laptops-in-2025-a-developers-guide-to-hardware-distros-and-making-the-switch-364p</link>
      <guid>https://dev.to/rasulkireev/linux-laptops-in-2025-a-developers-guide-to-hardware-distros-and-making-the-switch-364p</guid>
      <description>&lt;p&gt;As Intel-based Macs approach their final supported macOS version, many developers are evaluating Linux as a primary operating system for their laptops. The landscape for Linux on laptops in 2025 appears mature and promising, though not without its considerations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hardware: The Foundation of Your Linux Experience
&lt;/h3&gt;

&lt;p&gt;Hardware compatibility remains a pivotal factor. While many users report flawless experiences, particularly with slightly older or well-supported hardware like Lenovo's Yoga series (even recent models with 12th Gen Intel CPUs), caution is advised for the newest, most specialized components. Features such as Apple's XDR-quality displays or highly nuanced touchpad gestures might not have perfect support out-of-the-box on all Linux distributions. Investing time in researching specific laptop models and their Linux compatibility is highly recommended.&lt;/p&gt;

&lt;p&gt;For those seeking a more guaranteed experience, several vendors specialize in Linux laptops:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;System76:&lt;/strong&gt; Known for powerful machines, even offering configurations with high-end GPUs like the RTX 5090, and they develop their own Ubuntu-based Pop!_OS.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Framework:&lt;/strong&gt; Offers modular, repairable laptops with good Linux support, appealing to users who value sustainability and customization. Arch Linux is a common choice for these.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Tuxedo Computers:&lt;/strong&gt; A strong option for users in the EU, providing a range of Linux-preinstalled laptops.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even Chromebooks can be repurposed by installing most mainstream Linux distributions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Navigating the World of Distributions and Desktops
&lt;/h3&gt;

&lt;p&gt;The sheer number of Linux distributions can seem overwhelming, but it also offers unparalleled choice. For developers accustomed to macOS or Windows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Debian with KDE Plasma:&lt;/strong&gt; Some users find KDE Plasma, running on a stable base like Debian, offers a more familiar experience, particularly regarding text anti-aliasing (similar to ClearType) and traditional taskbar setups. This combination is often praised for its stability and speed, even on older hardware.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Fedora Silverblue:&lt;/strong&gt; An increasingly popular choice, offering an immutable OS design for enhanced stability and reliability. It often ships with GNOME, which can be customized.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Ubuntu and Pop!_OS:&lt;/strong&gt; Frequently recommended for users new to Linux due to their large communities, ease of use, and broad hardware support.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Arch Linux:&lt;/strong&gt; Favored by users who want deep customization and a rolling-release model, though it requires a more hands-on approach to installation and maintenance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Desktop environments like GNOME and KDE Plasma are the most common, with user preference often boiling down to workflow, aesthetics, and specific features like text rendering. Some users find GNOME's default text rendering less ideal compared to KDE or Windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Developer's Playground
&lt;/h3&gt;

&lt;p&gt;For software development, Linux is widely regarded as an excellent platform. It supports a vast array of tools, from classic command-line editors like Emacs and Vim to modern IDEs such as VS Code (or its open-source version, VSCodium), Sublime Text, IntelliJ IDEA, and Zed. The transition for developers is generally smooth, with many finding they don't miss their previous environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overall Sentiment
&lt;/h3&gt;

&lt;p&gt;The consensus is that Linux on laptops is not only viable but a strong contender, especially for developers. While initial setup and hardware choices require some attention, the benefits of stability, performance, customization, and the ability to revive older hardware make it an attractive option. Many have found long-term satisfaction and productivity using Linux on their laptops.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>laptop</category>
      <category>developer</category>
      <category>debian</category>
    </item>
    <item>
      <title>How to Prove Future Claims: A Guide to Cryptographic Foreshadowing</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Mon, 26 May 2025 14:18:12 +0000</pubDate>
      <link>https://dev.to/rasulkireev/how-to-prove-future-claims-a-guide-to-cryptographic-foreshadowing-50fg</link>
      <guid>https://dev.to/rasulkireev/how-to-prove-future-claims-a-guide-to-cryptographic-foreshadowing-50fg</guid>
      <description>&lt;p&gt;A user on Hacker News posed an intriguing question: how can one foreshadow specific information and only reveal it at a future date, while also providing irrefutable proof that the information was recorded &lt;em&gt;before&lt;/em&gt; its eventual public disclosure? This problem touches upon concepts of trust, verification, and the integrity of time-stamped data.&lt;/p&gt;

&lt;p&gt;The discussion yielded a practical and widely accepted cryptographic solution, detailed in a key comment. Here's a breakdown of the proposed method:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Cryptographic Proof-of-Prior-Knowledge Method
&lt;/h3&gt;

&lt;p&gt;The core idea revolves around using cryptographic hashes to create a "digital fingerprint" of your secret information, publishing this fingerprint publicly, and then revealing the original information later.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prepare Your Document:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Compile the information you wish to foreshadow into a digital document. This could be a text file, a PDF, or any other file format.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Crucial Tip:&lt;/strong&gt; The content of this document should be substantial. As the commenter noted, if the text is too short (e.g., a single sentence or a few words), it might be possible for someone to brute-force guess the content that produces the same hash, undermining your proof. Longer text makes this computationally infeasible.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Generate a Cryptographic Hash:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Use a strong cryptographic hash function, like SHA256 (as suggested in the example &lt;code&gt;Sha256 a9774a1a6ebf564cc408cfd86b5f2c06c13d830e143989714d958d34f325db13&lt;/code&gt;), to compute a unique hash sum of your document. This hash is a fixed-length string of characters that acts as a digital fingerprint. Even a tiny change in the document will result in a completely different hash.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Publish the Hash Publicly and Securely:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  This is the "foreshadowing" step. Publish the generated hash in a place that is:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Publicly accessible:&lt;/strong&gt; So others can see it.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Timestamped:&lt;/strong&gt; So there's a clear record of &lt;em&gt;when&lt;/em&gt; it was published.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Immutable (or difficult to alter post-facto):&lt;/strong&gt; To ensure the integrity of the timestamp.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  Examples of suitable platforms mentioned or implied by the discussion include:

&lt;ul&gt;
&lt;li&gt;  Social media (e.g., Mastodon timeline, Reddit, Hacker News comments)&lt;/li&gt;
&lt;li&gt;  A public blockchain transaction (e.g., in an &lt;code&gt;OP_RETURN&lt;/code&gt; field – though not explicitly mentioned, it fits the criteria)&lt;/li&gt;
&lt;li&gt;  An advertisement in a national printed newspaper (a traditional, but effective, method for a widely accepted timestamp).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  When publishing, include a clear statement, such as the example provided: “My prediction will be revealed on Dec 31 2025. Sha256 a9774a1a6ebf564cc408cfd86b5f2c06c13d830e143989714d958d34f325db13.”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reveal the Original Document:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  On or after the specified future date, publish the original document you created in Step 1.&lt;/li&gt;
&lt;li&gt;  Anyone can then independently download this document, calculate its SHA256 hash (or whichever algorithm was used), and compare it to the hash you published earlier. If the hashes match, it provides strong proof that the document (and its contents) existed in that exact form at the time the hash was originally published.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why This Method Works
&lt;/h3&gt;

&lt;p&gt;This technique leverages the fundamental properties of cryptographic hash functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Deterministic:&lt;/strong&gt; The same input will always produce the same hash.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Pre-image resistance:&lt;/strong&gt; It's computationally infeasible to find the original input (your document) given only its hash, especially for non-trivial documents.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Second pre-image resistance/Collision resistance:&lt;/strong&gt; It's computationally infeasible to find a &lt;em&gt;different&lt;/em&gt; document that produces the same hash.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By publishing the hash first, you commit to the content without revealing it. The public, timestamped nature of the hash publication prevents you from changing the document later and claiming it was the original. This method offers a robust way to foreshadow events, make sealed predictions, or establish prior art for an idea, ensuring that when the time comes for the reveal, you have verifiable proof of when your information was first recorded.&lt;/p&gt;

</description>
      <category>hashing</category>
      <category>knowledge</category>
      <category>timestamping</category>
      <category>cryptography</category>
    </item>
    <item>
      <title>The Hidden Secret to Get the Job of Your Dreams</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Tue, 29 Apr 2025 10:06:00 +0000</pubDate>
      <link>https://dev.to/rasulkireev/the-hidden-secret-to-get-the-job-of-your-dreams-2f27</link>
      <guid>https://dev.to/rasulkireev/the-hidden-secret-to-get-the-job-of-your-dreams-2f27</guid>
      <description>&lt;p&gt;Want to stand out?&lt;/p&gt;

&lt;p&gt;Video introductions are your secret weapon in today's competitive tech job market. They offer a personal touch that resumes simply can't match. This article will show you how to craft a compelling video intro and leverage &lt;code&gt;gettjalerts.com&lt;/code&gt; to find the perfect email addresses to send it to.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Craft a Killer Video Intro
&lt;/h3&gt;

&lt;p&gt;Your video intro is your first impression. Make it count!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Keep it concise:&lt;/strong&gt; Aim for 30-60 seconds. Recruiters are busy.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Highlight key skills:&lt;/strong&gt; Focus on skills relevant to the specific job. Tailor your message!&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Show your personality:&lt;/strong&gt; Let your enthusiasm shine through. Be authentic.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;End with a call to action:&lt;/strong&gt; Encourage them to view your resume or portfolio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I once helped a junior developer land a coveted role at a startup by suggesting he create a short video showcasing his coding projects. He got the job because the hiring manager was impressed by his initiative and personality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical Application:&lt;/strong&gt; Script your video, practice your delivery, and record in a well-lit, quiet environment. Use a professional tone.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Find the Right Email Addresses with gettjalerts.com
&lt;/h3&gt;

&lt;p&gt;Sending your video to the right person is crucial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Use &lt;code&gt;gettjalerts.com&lt;/code&gt; to find tech companies that are hiring.&lt;/strong&gt; Check out the &lt;a href="https://gettjalerts.com/jobs/companies/" rel="noopener noreferrer"&gt;Companies that are hiring right now&lt;/a&gt; page.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Identify relevant job postings.&lt;/strong&gt; Explore the &lt;a href="https://gettjalerts.com/jobs/" rel="noopener noreferrer"&gt;Available Jobs - March 2025&lt;/a&gt; to find opportunities that align with your skills.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Research company websites and LinkedIn.&lt;/strong&gt; Look for hiring managers or recruiters in the specific department you're targeting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;gettjalerts.com&lt;/code&gt; can help you discover companies and job titles that are in demand. For example, check out the &lt;a href="https://gettjalerts.com/jobs/titles/" rel="noopener noreferrer"&gt;Tech Job Titles that are in demand right now&lt;/a&gt; page to see what roles are trending.&lt;/p&gt;

&lt;p&gt;I remember struggling to find the right contact information when I was applying for jobs. Using a tool like &lt;code&gt;gettjalerts.com&lt;/code&gt; would have saved me so much time and effort.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical Application:&lt;/strong&gt; Combine &lt;code&gt;gettjalerts.com&lt;/code&gt; with LinkedIn to build a targeted list of email addresses for your video intro.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Follow Up Strategically
&lt;/h3&gt;

&lt;p&gt;Don't just send your video and hope for the best.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Personalize your email:&lt;/strong&gt; Reference something specific about the company or role.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Keep it brief:&lt;/strong&gt; Reiterate your key skills and express your enthusiasm.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Follow up within a week:&lt;/strong&gt; A gentle reminder can make all the difference.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I once received a follow-up email from a candidate that included a personalized video response to a question I had asked in the initial interview. It showed me that he was truly engaged and interested in the role.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical Application:&lt;/strong&gt; Track your emails and follow-up consistently. Persistence pays off.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;A video introduction can be a game-changer in your tech job search. By crafting a compelling video and using &lt;code&gt;gettjalerts.com&lt;/code&gt; to find the right email addresses, you can significantly increase your chances of landing your dream job. &lt;/p&gt;

&lt;p&gt;Ready to take your job search to the next level? Head over to &lt;code&gt;gettjalerts.com&lt;/code&gt; and start exploring the latest tech job opportunities. What are you waiting for?&lt;/p&gt;

</description>
      <category>career</category>
      <category>hiring</category>
      <category>learning</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Create Smarter &amp; Better Git Commits with AI</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Fri, 07 Feb 2025 07:53:47 +0000</pubDate>
      <link>https://dev.to/rasulkireev/create-smarter-better-git-commits-with-ai-50lm</link>
      <guid>https://dev.to/rasulkireev/create-smarter-better-git-commits-with-ai-50lm</guid>
      <description>&lt;p&gt;How many times have you stared at your terminal, trying to craft the perfect git commit message? Probably not much.&lt;/p&gt;

&lt;p&gt;I know what you have done often though...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nt"&gt;--all&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"fix"&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are a super lazy person like, me you maybe even created a git alias for that and only have to do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git cm &lt;span class="s2"&gt;"fix"&lt;/span&gt;
gp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Today I decided to change this forever. I decided to be the most thoughtful person in he world and think about my future self an anyone who is going to search for my code in the future...&lt;/p&gt;

&lt;p&gt;Enter &lt;code&gt;commit&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🙏 The Script
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

check_git_repo&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; git rev-parse &lt;span class="nt"&gt;--is-inside-work-tree&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;1
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

check_changes&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git status &lt;span class="nt"&gt;--porcelain&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;0
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

generate_commit_message&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;diff_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;files_changed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git status &lt;span class="nt"&gt;--porcelain&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"Files changed:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="nv"&gt;$files_changed&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Changes:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="nv"&gt;$diff_content&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
        llm &lt;span class="nt"&gt;-m&lt;/span&gt; anthropic/claude-3-5-sonnet-latest &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="s2"&gt;"Generate a git commit message for these changes. The message must have:

        1. TITLE LINE: A specific, concise summary (max 50 chars) that clearly
           describes the primary change or feature. This should not be generic like
           'Update files' but rather describe the actual change like 'Add user
           authentication to API endpoints'

        2. BLANK LINE

        3. DETAILED DESCRIPTION: A thorough explanation including:
           - What changes were made
           - Why they were necessary
           - Any important technical details
           - Breaking changes or important notes
           Wrap this at 72 chars.

        IMPORTANT:
        - Output ONLY the commit message
        - Make sure the title is specific to these changes
        - Focus on the what and why, not just the how"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Main execution&lt;/span&gt;
main&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    check_git_repo
    check_changes
    git add &lt;span class="nt"&gt;--all&lt;/span&gt;
    &lt;span class="nv"&gt;commit_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;generate_commit_message&lt;span class="si"&gt;)&lt;/span&gt;
    git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$commit_message&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

main &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚒️ Breaking it Down
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Repository Validation&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;check_git_repo&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; git rev-parse &lt;span class="nt"&gt;--is-inside-work-tree&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;1
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function ensures we're working within a git repository.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Change Detection&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;check_changes&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git status &lt;span class="nt"&gt;--porcelain&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;0
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verifies that there are actually changes to commit.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AI-Powered Message Generation&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;generate_commit_message&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;diff_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;files_changed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git status &lt;span class="nt"&gt;--porcelain&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"Files changed:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="nv"&gt;$files_changed&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Changes:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="nv"&gt;$diff_content&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
        llm &lt;span class="nt"&gt;-m&lt;/span&gt; anthropic/claude-3-5-sonnet-latest &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="s2"&gt;"Generate a git commit message for these changes. The message must have:

        1. TITLE LINE: A specific, concise summary (max 50 chars) that clearly
           describes the primary change or feature. This should not be generic like
           'Update files' but rather describe the actual change like 'Add user
           authentication to API endpoints'

        2. BLANK LINE

        3. DETAILED DESCRIPTION: A thorough explanation including:
           - What changes were made
           - Why they were necessary
           - Any important technical details
           - Breaking changes or important notes
           Wrap this at 72 chars.

        IMPORTANT:
        - Output ONLY the commit message
        - Make sure the title is specific to these changes
        - Focus on the what and why, not just the how"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the magic happens - the script analyzes your changes and uses AI to generate a meaningful commit message.&lt;/p&gt;

&lt;p&gt;The script uses &lt;a href="https://simonwillison.net/" rel="noopener noreferrer"&gt;Simon Willison&lt;/a&gt;'s &lt;code&gt;llm&lt;/code&gt; &lt;a href="https://github.com/simonw/llm" rel="noopener noreferrer"&gt;command-line tool&lt;/a&gt;, which is an incredibly useful utility for interacting with various AI models directly from your terminal. Head over to his &lt;a href="https://llm.datasette.io/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; to learn more about it. How to set it up and actually use it.&lt;/p&gt;

&lt;p&gt;Please note that I use anthropic's model in this script, which means you will have to set up the &lt;a href="https://github.com/simonw/llm-anthropic" rel="noopener noreferrer"&gt;llm-anthropic&lt;/a&gt; plugin.&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 Setting it up
&lt;/h2&gt;

&lt;p&gt;To run this, just create a commit file and add it your bin directory, such that it ends up in you PATH.&lt;/p&gt;

&lt;p&gt;Don't forget to run&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="nb"&gt;chmod&lt;/span&gt; +x ~/.local/bin/commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to make the script executable. Of course, update the path to the script depending on where you save it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎉 Yay
&lt;/h2&gt;

&lt;p&gt;Now after working hard on your code you'll just have to run &lt;code&gt;commit&lt;/code&gt; and you'll get a commit message generated by AI.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>cli</category>
      <category>git</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Django Codebase Updates: January 2025</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Fri, 07 Feb 2025 07:52:04 +0000</pubDate>
      <link>https://dev.to/rasulkireev/django-codebase-updates-january-2025-52e6</link>
      <guid>https://dev.to/rasulkireev/django-codebase-updates-january-2025-52e6</guid>
      <description>&lt;p&gt;Here's a structured summary of Django's development activity in January 2025:&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;The month showed significant development activity with 90 commits focusing on several major themes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extensive work on composite primary key support and validation&lt;/li&gt;
&lt;li&gt;Bug fixes and improvements for database operations&lt;/li&gt;
&lt;li&gt;Documentation updates and cleanup&lt;/li&gt;
&lt;li&gt;Security and dependency updates&lt;/li&gt;
&lt;li&gt;Test suite improvements and optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Changes and Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Major Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Added automatic model imports to Django shell command, a GSoC 2024 project (by Salvo Polizzi - &lt;a href="https://github.com/django/django/commit/fc28550fe4e0582952993976edc62971bd5345a8" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Implemented double squashing of migrations capability (by Georgi Yanchev - &lt;a href="https://github.com/django/django/commit/64b1ac7292c72d3551b2ad70b2a78c8fe4af3249" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Added ability to customize admin password change form (by Mohammadreza Eskandari - &lt;a href="https://github.com/django/django/commit/12b9ef38b3ff7f5b8b24a5f42e8923fdb6db44bb" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Composite Primary Key Improvements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Added serialization support for composite primary keys (by Sarah Boyce - &lt;a href="https://github.com/django/django/commit/6a1a9c0eade674780060cf8af5f5b3375156cdd5" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Fixed password reset functionality with composite primary keys (by Sarah Boyce - &lt;a href="https://github.com/django/django/commit/23c6effac0c39669e17904165c9762f24b010cc5" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Added validation for non-local fields in composite primary keys (by Bendeguz Csirmaz - &lt;a href="https://github.com/django/django/commit/d83fb782d33aa7aaa1b2c995c648a59eddb46047" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Bug Fixes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fixed UnicodeEncodeError in email attachments (by greg - &lt;a href="https://github.com/django/django/commit/89e28e13ecbf9fbcf235e16d453c08bbf2271244" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Fixed bulk_update handling with multiple primary keys (by Sarah Boyce - &lt;a href="https://github.com/django/django/commit/5a2c1bc07d126ce32efaa157e712a8f3a7457b74" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Fixed RecursionError in FilteredRelation joins (by Peter DeVita - &lt;a href="https://github.com/django/django/commit/8eca4077f60fa0705ecfd9437c9ceaeef7a3808b" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security and Dependencies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Updated minimum supported package versions for Python 3.12 compatibility (by Mariusz Felisiak - &lt;a href="https://github.com/django/django/commit/d9af197801376fae178761cac12d57178a738cf4" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Added documentation for security vulnerability CVE-2024-56374 (by Natalia - &lt;a href="https://github.com/django/django/commit/f2a1dcaa53626ff11b921ef142b780a8fd746d32" rel="noopener noreferrer"&gt;commit&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Development Patterns and Contributors
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Active Contributors: Sarah Boyce, Simon Charette, Jacob Walls, and Mariusz Felisiak were particularly active&lt;/li&gt;
&lt;li&gt;Focus Areas: Strong emphasis on improving composite primary key support and fixing related edge cases&lt;/li&gt;
&lt;li&gt;Testing: Significant attention to test coverage with many commits including comprehensive test additions&lt;/li&gt;
&lt;li&gt;Documentation: Consistent updates to maintain accuracy and clarity of documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recommendations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Developers should review the new composite primary key functionality carefully as it represents a significant change&lt;/li&gt;
&lt;li&gt;Projects planning to upgrade should pay attention to the new minimum package version requirements for Python 3.12 compatibility&lt;/li&gt;
&lt;li&gt;Teams using Django's admin interface should evaluate the new password change form customization capabilities&lt;/li&gt;
&lt;li&gt;Consider using the new automatic model imports feature in Django shell for improved developer experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The month showed strong progress in both feature development and stability improvements, with particular attention to composite primary key support and developer experience enhancements.&lt;/p&gt;

</description>
      <category>django</category>
      <category>opensource</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>7 Simple Ways to Create Blog Posts That Actually Rank in Google</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Tue, 03 Dec 2024 09:44:04 +0000</pubDate>
      <link>https://dev.to/rasulkireev/7-simple-ways-to-create-blog-posts-that-actually-rank-in-google-46cl</link>
      <guid>https://dev.to/rasulkireev/7-simple-ways-to-create-blog-posts-that-actually-rank-in-google-46cl</guid>
      <description>&lt;p&gt;Creating blog content that ranks well in Google isn't just about writing great content anymore. With over 7 million blog posts published daily, you need a strategic approach to stand out and reach your target audience. In this guide, we'll explore seven proven methods to create blog posts that actually climb the search rankings.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Start with Solid Keyword Research
&lt;/h2&gt;

&lt;p&gt;Before writing a single word, understand what your audience is searching for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use keyword research tools to identify relevant search terms&lt;/li&gt;
&lt;li&gt;Focus on long-tail keywords with manageable competition&lt;/li&gt;
&lt;li&gt;Analyze search intent behind your target keywords&lt;/li&gt;
&lt;li&gt;Consider keyword difficulty and monthly search volume&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Optimize Your Content Structure
&lt;/h2&gt;

&lt;p&gt;A well-structured post helps both readers and search engines understand your content:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create clear, descriptive headings using H2 and H3 tags&lt;/li&gt;
&lt;li&gt;Include your target keyword in the first 100 words&lt;/li&gt;
&lt;li&gt;Write short, scannable paragraphs&lt;/li&gt;
&lt;li&gt;Use bullet points and numbered lists for better readability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Create Comprehensive Content
&lt;/h2&gt;

&lt;p&gt;Google favors content that thoroughly covers a topic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aim for detailed, in-depth articles (1,500+ words)&lt;/li&gt;
&lt;li&gt;Cover all relevant aspects of your topic&lt;/li&gt;
&lt;li&gt;Include supporting data and statistics&lt;/li&gt;
&lt;li&gt;Address common questions your audience might have&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Focus on User Experience
&lt;/h2&gt;

&lt;p&gt;Engagement metrics matter for SEO:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure fast loading times&lt;/li&gt;
&lt;li&gt;Make content mobile-friendly&lt;/li&gt;
&lt;li&gt;Use clear fonts and adequate spacing&lt;/li&gt;
&lt;li&gt;Include relevant images and videos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Implement Technical SEO Best Practices
&lt;/h2&gt;

&lt;p&gt;Don't overlook the technical aspects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimize your meta title and description&lt;/li&gt;
&lt;li&gt;Use proper header hierarchy&lt;/li&gt;
&lt;li&gt;Include alt text for images&lt;/li&gt;
&lt;li&gt;Create SEO-friendly URLs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Build Quality Backlinks
&lt;/h2&gt;

&lt;p&gt;Backlinks remain a crucial ranking factor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create linkable assets (infographics, studies, tools)&lt;/li&gt;
&lt;li&gt;Reach out to industry influencers&lt;/li&gt;
&lt;li&gt;Guest post on relevant websites&lt;/li&gt;
&lt;li&gt;Promote content through social media&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Regular Content Updates
&lt;/h2&gt;

&lt;p&gt;Keep your content fresh and relevant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update old posts with new information&lt;/li&gt;
&lt;li&gt;Add recent statistics and examples&lt;/li&gt;
&lt;li&gt;Remove outdated content&lt;/li&gt;
&lt;li&gt;Monitor and improve based on performance&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Putting It All Together
&lt;/h2&gt;

&lt;p&gt;Creating content that ranks isn't a one-time effort. It requires consistent attention to both on-page and off-page factors. Tools like SEO Blog Bot can help streamline this process by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyzing your website's current content performance&lt;/li&gt;
&lt;li&gt;Suggesting relevant blog topics based on your niche&lt;/li&gt;
&lt;li&gt;Generating SEO-optimized content structure&lt;/li&gt;
&lt;li&gt;Providing keyword-rich content suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Implementing these seven strategies will significantly improve your chances of ranking in Google. Remember, SEO is a marathon, not a sprint. Focus on creating valuable content for your audience while following these optimization techniques.&lt;/p&gt;

&lt;p&gt;Ready to start creating content that ranks? Try &lt;a href="https://seoblogbot.com" rel="noopener noreferrer"&gt;SEO Blog Bot&lt;/a&gt; today and transform your content strategy with AI-powered SEO optimization.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Stay consistent with your content creation efforts and regularly monitor your rankings to adjust your strategy as needed.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>contentwriting</category>
      <category>google</category>
      <category>writing</category>
    </item>
    <item>
      <title>Improve your Django Code with pre-commit</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Wed, 05 Apr 2023 12:22:42 +0000</pubDate>
      <link>https://dev.to/rasulkireev/improve-your-django-code-with-pre-commit-4pgk</link>
      <guid>https://dev.to/rasulkireev/improve-your-django-code-with-pre-commit-4pgk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Update (04/01/2023): A kind reddit user by the name of &lt;a href="https://www.reddit.com/user/lanemik/" rel="noopener noreferrer"&gt;lanemik&lt;/a&gt; suggested I give &lt;a href="https://github.com/charliermarsh/ruff" rel="noopener noreferrer"&gt;ruff&lt;/a&gt; a go. So i decided to add it to the guide.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the previous tutorial we have finished styling our Authentication pages. Before we go any further I would like to introduce you to an awesome developer tool that will improve your code, &lt;strong&gt;a lot&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Meet &lt;a href="https://pre-commit.com" rel="noopener noreferrer"&gt;pre-commit&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pre-commit is a tool that allows you to automate the process of checking your code for errors and issues before committing it to your repository, hence the name. &lt;/p&gt;

&lt;p&gt;In simple terms, it will help you catch bugs and errors. Not only that, but it will also be able to sort your imports based on PEP recommendation as well as lint your code for better readability.&lt;/p&gt;

&lt;p&gt;In this guide, I will show you how to set it up, and then I will share my favorite hooks that I use in all my projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;See all the code from this tutorial &lt;a href="https://github.com/builtwithdjango/basic-django/pull/2" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install pre-commit&lt;/li&gt;
&lt;li&gt;Create &lt;code&gt;.pre-commit-config.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Start adding hooks. Here are the ones I recommend:

&lt;ul&gt;
&lt;li&gt;black&lt;/li&gt;
&lt;li&gt;isort&lt;/li&gt;
&lt;li&gt;flake8&lt;/li&gt;
&lt;li&gt;pylint&lt;/li&gt;
&lt;li&gt;djlint&lt;/li&gt;
&lt;li&gt;poetry export&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Follow Along
&lt;/h2&gt;

&lt;p&gt;Before we continue, I would like to mention that you can look at all the code that we wrote in this tutorial by looking into the &lt;a href="https://github.com/builtwithdjango/basic-django/pull/2" rel="noopener noreferrer"&gt;pre-commit PR&lt;/a&gt; on the &lt;a href="https://github.com/builtwithdjango/basic-django" rel="noopener noreferrer"&gt;basic-django repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All the previous tutorials have been applied to that repo too. If you have any questions or concerns, feel free to leave a comment below or on the PR. I'll try to respond as soon as I see the comment.&lt;/p&gt;

&lt;p&gt;Finally, last comment before we begin is that you are following the whole series that you should see the same results as I will. However, if you are using a different repo, or you have wrote more code, then the &lt;code&gt;pre-commit&lt;/code&gt; messages that you will receive might be slightly different.&lt;/p&gt;

&lt;p&gt;But don't worry, even if they are different, they should be clear and very actionable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-Commit
&lt;/h2&gt;

&lt;p&gt;I am going to go through each step with you, but I encourage you to check out the &lt;a href="https://pre-commit.com" rel="noopener noreferrer"&gt;official website&lt;/a&gt;. The instructions they have are very useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install Pre-Commit
&lt;/h3&gt;

&lt;p&gt;You can install it on your whole system (MacOS) with &lt;code&gt;brew install pre-commit&lt;/code&gt;, but we are also going to add it to our project explicitly with by running &lt;code&gt;poetry add --group dev pre-commit&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please note, the &lt;code&gt;--group dev&lt;/code&gt;, this will add the dependency to the dev section. This is useful because when we install libraries in the production setting those won't be installed, thus using less storage space and increasing installation/deployment steps.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's confirm that the library has been installed by running &lt;code&gt;poetry run pre-commit --version&lt;/code&gt;. If you don't know what this &lt;code&gt;poetry run&lt;/code&gt; stuff is, I recommend you check my &lt;a href="https://builtwithdjango.com/blog/basic-django-setup" rel="noopener noreferrer"&gt;Poetry guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.  Create a &lt;code&gt;pre-commit&lt;/code&gt; Config File
&lt;/h3&gt;

&lt;p&gt;Next, you will need to create a &lt;code&gt;.pre-commit-config.yaml&lt;/code&gt; file in the root of your repository. This is where the magic happens. Once you create the file add the following text to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;repos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pre-commit/pre-commit-hooks&lt;/span&gt;
    &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v4.4.0&lt;/span&gt;
    &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check-yaml&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;end-of-file-fixer&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trailing-whitespace&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file defines the pre-commit hooks that will be run. For example, in this specific case, we are using 3 hooks provided by pre-commit: &lt;code&gt;check-yaml&lt;/code&gt;, &lt;code&gt;end-of-file-fixer&lt;/code&gt;, &lt;code&gt;trailing-whitespace&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the structure we are going to follow when we want to add new hooks. Under the &lt;code&gt;repos&lt;/code&gt; array we will specify an object that has the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;repo&lt;/strong&gt;: the location of the hook (some libraries provide those hooks, but if one is not provided, we can write our own, we will do that later in that guide)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;rev&lt;/strong&gt;: this is the version/release of the repo you have specified. If you look at the &lt;a href="https://github.com/pre-commit/pre-commit-hooks" rel="noopener noreferrer"&gt;&lt;code&gt;pre-commit-hooks&lt;/code&gt;&lt;/a&gt; library you can see it in the releases section: &lt;img src="https://media2.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%2F67gtk7eytzy14mz24ep6.png" alt="pre-commit repo release" width="800" height="329"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hooks&lt;/strong&gt;: now to the actual hooks that will be used from that repo. Again, check the pre-commit-hook repo to see what hooks are available (there are maaany), maybe you'll find them useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These specific hooks are pretty self explanatory, so instead of describing each one of those, let's just run this and see what happens.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please note, that if you are running it outside of your repo, it is not likely to do anything. You should set this up as part of some repo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3.  Install and Run your Hooks for the first time
&lt;/h3&gt;

&lt;p&gt;Once you have created your config file, you need to install the hooks specified in the file. You can do this by running: &lt;code&gt;poetry run pre-commit install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once this command is done, run &lt;code&gt;poetry run pre-commit run --all-files&lt;/code&gt; which will run these hooks against your repo. You should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fpuawglwvp5wmdy5wfldc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fpuawglwvp5wmdy5wfldc.png" alt="running pre-commit for the first time" width="587" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, what happened is that &lt;code&gt;pre-commit&lt;/code&gt; checked all the files in the library and "fixed" them based on the hooks you have set up.&lt;/p&gt;

&lt;p&gt;!!! danger "&lt;strong&gt;!! Warning !!&lt;/strong&gt;"&lt;br&gt;
    These first checks are harmless, so there is no worry about running them with --all-file. &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;However, later we will start adding hooks that format your code. If you have a large codebase, I don't recommend you run the `pre-commit run --all-files`, since that will affect a lot of the code. 

Instead, you may want to start testing that the new hooks are working by running on one file at a time like so `pre-commit run --files YOUR_FILENAME`.

If you would still prefer to "fix" the whole codebase, I will recommend you do it slowly, step, by step, like I do in this tutorial.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  4.  Use Pre-Commit
&lt;/h3&gt;

&lt;p&gt;In the future you will not be using &lt;code&gt;poetry run pre-commit run --all-files&lt;/code&gt;, instead pre-commit will automatically on all the files that you are committing to your repo.&lt;/p&gt;

&lt;p&gt;Here is the general workflow that will now happen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You work on a feature for your website and have changed a bunch of files.&lt;/li&gt;
&lt;li&gt;You run &lt;code&gt;git add --all&lt;/code&gt; (doesn't have to be &lt;code&gt;--all&lt;/code&gt; you could add files one by one, whatever is your preference)&lt;/li&gt;
&lt;li&gt;Then, you will run &lt;code&gt;git commit -m "adding new feature"&lt;/code&gt;. At that stage pre-commit starts. If all the checks have Passed, then the commit will go through and you can then run &lt;code&gt;git push&lt;/code&gt;. If, on the other hand, at least one check fails commit will not go through.&lt;/li&gt;
&lt;li&gt;Depending on your set up (which we will discuss later) either of the two things will happen. 

&lt;ol&gt;
&lt;li&gt;pre-commit have fixed those mistakes automatically (like in the example above we saw pre-commit say that a number of files have been "fixed") &lt;/li&gt;
&lt;li&gt;pre-commit won't fix mistakes, but will point you towards where those foxes are, so that you can fix them yourself.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;In either case once the fixes are done, you want to re-add the fixed versions of the file with &lt;code&gt;git add --all&lt;/code&gt; and re-try running the  &lt;code&gt;git commit -m "adding new feature"&lt;/code&gt;. This time, if all things have been fixed the commit will go through.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I know that this can sound a little tedious or slow. But once you go through this a couple of times, you will realize how quick, easy and useful this is.&lt;/p&gt;
&lt;h2&gt;
  
  
  Good Hooks to Use
&lt;/h2&gt;

&lt;p&gt;Now that the setup is done, let go through some of my favorite hooks that I use in almost all my projects. The first three you have already seen, I do use them everywhere.&lt;/p&gt;
&lt;h3&gt;
  
  
  Black
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/psf/black" rel="noopener noreferrer"&gt;Black&lt;/a&gt; is a Python code formatter. This means that when this hook will run, all the files that you want to commit will be checked for any inconsistencies and bad styling (&lt;a href="https://pep8.org" rel="noopener noreferrer"&gt;based on PEP 8 standard&lt;/a&gt;). This hook will automatically fix those issues.&lt;/p&gt;

&lt;p&gt;Before we add this hook, let's do something first. Add &lt;code&gt;exclude: ^migrations/&lt;/code&gt; to the top of your &lt;code&gt;pre-commit&lt;/code&gt; config file. So that it will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .pre-commit-config.yaml&lt;/span&gt;
&lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.*migrations\/.*&lt;/span&gt;
&lt;span class="na"&gt;repos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make sure that the files that Django migration generates are not touched. You don't have to do that. I, personally, I think it makes sense not to touch files that are autogenerated by Django.&lt;/p&gt;

&lt;p&gt;Alright, now that this is out of the way, let's add &lt;code&gt;black&lt;/code&gt; to pre-commit. All you have to do is add the following lines to the pre-commit config file, right after the first "repo":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.*migrations\/.*&lt;/span&gt;
&lt;span class="na"&gt;repos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pre-commit/pre-commit-hooks&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/psf/black&lt;/span&gt;
  &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;22.12.0&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;black&lt;/span&gt;
    &lt;span class="na"&gt;language_version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3.9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep in mind that at the time that you are reading, &lt;code&gt;black&lt;/code&gt; might have a newer version available. You should go to &lt;a href="https://github.com/psf/black" rel="noopener noreferrer"&gt;the repo&lt;/a&gt; and check the latest available version (just like described above).&lt;/p&gt;

&lt;p&gt;Another thing to keep in mind is that you should change the language version depending on what you are targeting. For example, when setting up the &lt;code&gt;basic-django&lt;/code&gt; repo we specified that this project will be version 3.9.&lt;/p&gt;

&lt;p&gt;!!! note "Optional"&lt;br&gt;
    If you are using poetry in your project, like I described in &lt;a href="https://builtwithdjango.com/blog/basic-django-setup" rel="noopener noreferrer"&gt;a previous post&lt;/a&gt; you can also add another layer of configuration. In you &lt;code&gt;pyproject.toml&lt;/code&gt; file you can add the following block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[tool.black]&lt;/span&gt;
&lt;span class="py"&gt;line-length&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;
&lt;span class="py"&gt;target-version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'py39'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;include&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'\.pyi?$'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;!!! note "Optional, continued"&lt;br&gt;
    Black will you these configurations when being ran by pre-commit. To see the full list of available configurations, check out &lt;a href="https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html" rel="noopener noreferrer"&gt;the official docs page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once you've added it, you can test by running &lt;code&gt;poetry run pre-commit run --all-files&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You should see something like this:&lt;br&gt;
&lt;a href="https://media2.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%2F0i2er0xb8yrmiu8enco7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F0i2er0xb8yrmiu8enco7.png" alt="result of running black with pre-commit" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you do, congratulations!!! 8 files were formatted to adhere to the PEP-8 standard 🤘&lt;/p&gt;

&lt;p&gt;If something went wrong, please comment below, I'll take a look ASAP.&lt;/p&gt;

&lt;p&gt;We can move on to other hooks.&lt;/p&gt;
&lt;h3&gt;
  
  
  isort
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/pycqa/isort" rel="noopener noreferrer"&gt;isort&lt;/a&gt; is an awesome tool that will sort imports across your repo.&lt;/p&gt;

&lt;p&gt;You know the drill. Let's add this hook to the pre-commit config file. It will look like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;repos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt; &lt;span class="s"&gt;pre-commmit stuff&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt; &lt;span class="s"&gt;black stuff&lt;/span&gt;
 &lt;span class="s"&gt;- repo&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pycqa/isort&lt;/span&gt; 
   &lt;span class="s"&gt;rev&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5.12.0&lt;/span&gt; 
   &lt;span class="s"&gt;hooks&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; 
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;isort&lt;/span&gt; 
       &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;isort (python)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And optionally, but very much recommended add these configurations to the &lt;code&gt;pyproject.toml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[tool.isort]&lt;/span&gt;
&lt;span class="py"&gt;profile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"django"&lt;/span&gt;
&lt;span class="py"&gt;combine_as_imports&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;include_trailing_comma&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;line_length&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go over at what these do.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;isort has &lt;a href="https://pycqa.github.io/isort/docs/configuration/profiles.html" rel="noopener noreferrer"&gt;profiles&lt;/a&gt;, which let you choose what type of repo you have. This will slightly change the behaviour of the check.&lt;/li&gt;
&lt;li&gt;The next too are something that isort recommends for the django profile. &lt;code&gt;combine_as_imports&lt;/code&gt; will that imports with &lt;code&gt;as&lt;/code&gt; statement are combined and the &lt;code&gt;include_trailing_comma&lt;/code&gt; will keep the comma after the last import in a statement that imports multiple items.&lt;/li&gt;
&lt;li&gt;Next is the line length, which is &lt;strong&gt;important&lt;/strong&gt;. I ran into this problem a few times. Make sure that this number is the same as the one configure in black. If that is not the case, often times, these two will conflict with each other, correcting each others behavior.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's try running pre-commit again with &lt;code&gt;poetry run pre-commit run --all-files&lt;/code&gt;. You should see something like this:&lt;br&gt;
&lt;a href="https://media2.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%2F4onvi2piwiemiimeji0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4onvi2piwiemiimeji0g.png" alt="running pre-commit after adding isort" width="582" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please note,that black passed the test, since we habe already run it before, which is cool. Also, interesting to see the &lt;code&gt;fix end of files&lt;/code&gt; hook being triggered. Probably I added extra line in the pre-commit config file. Finally I can see that 2 files have been fixed by &lt;code&gt;isort&lt;/code&gt;, awesome. &lt;/p&gt;

&lt;p&gt;Let's move on!&lt;/p&gt;
&lt;h3&gt;
  
  
  flake8
&lt;/h3&gt;

&lt;p&gt;flake8 is yet another awesome tool that will help you check the style and quality of some python code.&lt;/p&gt;

&lt;p&gt;This one is going to be a liiiitle bit different. Instead configuring the behaviour in the pyproject.toml file like before we will create a separate file for it. &lt;/p&gt;

&lt;p&gt;But first, let's add to the pre-commit file first. As before check the latest version that is available in the github repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pycqa/flake8&lt;/span&gt;
  &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;6.0.0&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flake8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note create a &lt;code&gt;.flake8&lt;/code&gt; file at the root of your repository and add the following to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[flake8]
max-line-length=120
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's try running it with &lt;code&gt;poetry run pre-commit run --all-files&lt;/code&gt;. Here is what I got:&lt;br&gt;
&lt;a href="https://media2.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%2Fu099zpeo7h1xtfev8zca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fu099zpeo7h1xtfev8zca.png" alt="running pre-commit with flake8" width="588" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome. Couple of things to note. &lt;/p&gt;

&lt;p&gt;First, I did not talk about this before, but you can see in the first lines where &lt;code&gt;pre-commit&lt;/code&gt; is setting up the environment for flake8 (essentially checking if the hooks exist). If something went wrong at this stage, then it is likely that you entered url incorrect or that you added a non-existent version.&lt;/p&gt;

&lt;p&gt;Second, is that this plugin doesn't update the file for us. It just tells us what is currently wrong so that I can go and fix it myself before committing the new code, which is fantastic. Let's do exactly that.&lt;/p&gt;

&lt;p&gt;First, it doesn't like that the HTML string in the &lt;code&gt;utils.py&lt;/code&gt; file is too long. Black did not make it smaller, because it doesn't know how to operate on strings. There are two approaches we can take:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fix the line length by breaking up the svg code into multiple lines.&lt;/li&gt;
&lt;li&gt;Tell flake that this exact case is fine.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm going to opt for #2, since I don't care about the readability of the svg tag (no one actually "inspects" those). Plus, would be good to show how to tell packages to ignore some lines.&lt;/p&gt;

&lt;p&gt;I'm going to put the following comment &lt;code&gt;# noqa: E501&lt;/code&gt; on lines 16 and 17. The &lt;code&gt;E501&lt;/code&gt; comes from the message in the terminal. Same for the lines, flake8 tells me which lines are affected. After adding this comment to both lines, let's rerun the &lt;code&gt;pre-commit&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjwwd4ugk1vqvu9ngykif.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjwwd4ugk1vqvu9ngykif.png" alt="flake8  noqa" width="512" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et Voila! This specific message is gone. Now let's fix others. Looks like it is about unused imports. That should be easy to fix. Let's remove those import and rerun.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fpckyh64p3ew7zixvwg7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fpckyh64p3ew7zixvwg7t.png" alt="flake8 passed" width="564" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hooray! Let's move on to pylint.&lt;/p&gt;
&lt;h3&gt;
  
  
  pylint
&lt;/h3&gt;

&lt;p&gt;pylint is a linter and a static code analyzer just like flake8. It will check your code for any formatting issue as well as any performance issues. The difference is that pylint is a little more thorough and more customizable.&lt;/p&gt;

&lt;p&gt;I feel like those two complement each other. You don't have to set both of them up, but I sleep better when I know that two unrelated programs checked my code 🤣&lt;/p&gt;

&lt;p&gt;Set up for pylint is a little different. Here is a quote from the &lt;a href="https://pylint.readthedocs.io/en/latest/user_guide/installation/pre-commit-integration.html" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since &lt;code&gt;pylint&lt;/code&gt; needs to import modules and dependencies to work correctly, the hook only works with a local installation of &lt;code&gt;pylint&lt;/code&gt; (in your environment).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, we need to install pylint into our repo with &lt;code&gt;poetry add --group dev pylint&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Once &lt;code&gt;pylint&lt;/code&gt; was installed we will need to tell &lt;code&gt;pre-commit&lt;/code&gt; to use that specific version. Again, let's check the &lt;a href="https://pylint.readthedocs.io/en/latest/user_guide/installation/pre-commit-integration.html" rel="noopener noreferrer"&gt;docs for that&lt;/a&gt;. They recommend we do it that way (I removed a couple of args):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pylint&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pylint&lt;/span&gt;
      &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;poetry run pylint&lt;/span&gt;
      &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;system&lt;/span&gt;
      &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;python&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-rn"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Only display messages&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-sn"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Don't display the score&lt;/span&gt;
        &lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the change I made on the &lt;code&gt;entry&lt;/code&gt; line. Instead of running &lt;code&gt;pylint&lt;/code&gt;, we are telling &lt;code&gt;pre-commit&lt;/code&gt; to run &lt;code&gt;poetry run pylint&lt;/code&gt;, since that is the preferred way to invoke packages installed with poetry.&lt;/p&gt;

&lt;p&gt;One last thing to do before running the hooks is to create a config file, just like we did with &lt;code&gt;flake8&lt;/code&gt;. For this you are going to create a &lt;code&gt;pylintrc&lt;/code&gt; file at the roor of your project and copy the contents of the &lt;code&gt;pylintrc&lt;/code&gt; file from the &lt;code&gt;pylint&lt;/code&gt; repo (&lt;a href="https://github.com/pylint-dev/pylint/blob/main/pylintrc" rel="noopener noreferrer"&gt;here is the link to it&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;These are the recommended setting for pylint that we can configure in the future if we want.&lt;/p&gt;

&lt;p&gt;Let's run &lt;code&gt;poetry run pre-commit run --all-files&lt;/code&gt; to see what happens.&lt;/p&gt;

&lt;p&gt;Here is what I got.&lt;br&gt;
&lt;a href="https://media2.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%2Fnusmgek1oo3wdio8o4uk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnusmgek1oo3wdio8o4uk.png" alt="first pylint errors" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good, that means it's working. Before going further, I would like to show you another cool feature of pylint. Extensions.&lt;/p&gt;

&lt;p&gt;There is a Django extension that we can install and apply to the pylint check. Let's do that.&lt;/p&gt;

&lt;p&gt;Install with &lt;code&gt;poetry add --group dev pylint-django&lt;/code&gt;.  And add the 2 new lines to the args list, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;...&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-rn"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-sn"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--load-plugins=pylint_django"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# new&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--django-settings-module={NAME&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;OF&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;YOUR&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;REPO}.settings"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# new&lt;/span&gt;
        &lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's run &lt;code&gt;poetry run pre-commit run --all-files&lt;/code&gt; once again, to make sure everything is working correctly.&lt;/p&gt;

&lt;p&gt;Looks like pylint found the same 3 errors. I'm not going to go over them one by one, since they are very detailed, and more importantly, you might be seeing something else.&lt;/p&gt;

&lt;p&gt;The only note I'll make is that I will add&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--ignore=manage.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to the list of args, since this was generated by Django, and I don't want to lint that.&lt;/p&gt;

&lt;p&gt;So, let's use the magic of reading and see what it looks like after I modified the code to the pylint's liking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F7snpdhegdhpdkf4cxalg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F7snpdhegdhpdkf4cxalg.png" alt="pylint success" width="581" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice. Another useful check added to the list.&lt;/p&gt;

&lt;p&gt;I will tell you this... In my opinion, pylint is the hardest and the most annoying to setup and "please" in the future. However, it doesn't mean that you should do it. I think all (most) the error messages that it is showing are useful.&lt;/p&gt;

&lt;p&gt;If you encounter those error, at setup or at commit don't worry. Spend some time trying to fix them, or googling about them. This will make you a better dev for sure.&lt;/p&gt;

&lt;p&gt;Comment below, if something is not working for you. I'll try to help. &lt;/p&gt;

&lt;h3&gt;
  
  
  djlint
&lt;/h3&gt;

&lt;p&gt;For Django users, which you presumably are, this will be a God send! Check out &lt;a href="https://github.com/Riverside-Healthcare/djLint" rel="noopener noreferrer"&gt;the repo&lt;/a&gt;. This is an HTML linter... but for Django templates 🤯&lt;/p&gt;

&lt;p&gt;It will look for errors and inconsistencies in your HTML files. The setup for this one is straightforward.&lt;/p&gt;

&lt;p&gt;Add this to the pre-commit-config file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/Riverside-Healthcare/djLint&lt;/span&gt;
  &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1.19.16&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;djlint-django&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, I will add the following conf to the &lt;code&gt;pyproject.toml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[tool.djlint]&lt;/span&gt;
&lt;span class="py"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"django"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For all the conf options, check out the &lt;a href="https://djlint.com/docs/configuration/" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing to note is that I would recommend you put this "repo", before the "local" one. It is preferable to keep the "local" one last. So, in our case we would add this one right after &lt;code&gt;flake8&lt;/code&gt; one.&lt;/p&gt;

&lt;p&gt;And, as before make sure you are using the latest version. Let's give this a run with &lt;code&gt;poetry run pre-commit run --all-files&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F81nilr16kk6g6ygzg3i9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F81nilr16kk6g6ygzg3i9.png" alt="djlint first run" width="613" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oof, there is a lot to fix. Thankfully, errors are pretty clear.&lt;/p&gt;

&lt;p&gt;I've included the following ignores to my conf file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[tool.djlint]&lt;/span&gt;
&lt;span class="py"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"django"&lt;/span&gt;
&lt;span class="py"&gt;ignore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"H031"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Added H031 because keywords meta is no longer used. Everything else, fixed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftr0f2c648vnyfsjr8nkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftr0f2c648vnyfsjr8nkz.png" alt="fixed djlint" width="576" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  poetry export
&lt;/h3&gt;

&lt;p&gt;Final one that I like to use is the &lt;code&gt;poetry export&lt;/code&gt; hook. It used to be the case that we needed to add this one to the local repo, but no longer.&lt;/p&gt;

&lt;p&gt;This is useful if you don't want to install poetry on your prod server or in your Dockerfile. That is to say very useful.&lt;/p&gt;

&lt;p&gt;Instead of dealing with poetry in Docker or prod we will just have a nice and fresh "requirements.txt" file to use for out dependencies. Beautiful.&lt;/p&gt;

&lt;p&gt;To make this work add the following to your pre-commit config file. I put it right after the djlint hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/python-poetry/poetry&lt;/span&gt;
  &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.4.1'&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;poetry-export&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-f"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;requirements.txt"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-o"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;requirements.txt"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--without-hashes"&lt;/span&gt;
      &lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one doesn't require any configurations ♥️. To see other poetry hooks, check out &lt;a href="https://python-poetry.org/docs/master/pre-commit-hooks/" rel="noopener noreferrer"&gt;their docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fl9qib32o21d5gfk0rlt5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fl9qib32o21d5gfk0rlt5.png" alt="final check passed" width="581" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ruff
&lt;/h3&gt;

&lt;p&gt;A kind reddit user by the name of &lt;a href="https://www.reddit.com/user/lanemik/" rel="noopener noreferrer"&gt;lanemik&lt;/a&gt; suggested I give &lt;a href="https://github.com/charliermarsh/ruff" rel="noopener noreferrer"&gt;ruff&lt;/a&gt; a go. I have heard of this tool before, but never actually gave it a go.&lt;/p&gt;

&lt;p&gt;According to the README&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ruff can be used to replace &lt;a href="https://pypi.org/project/flake8/" rel="noopener noreferrer"&gt;Flake8&lt;/a&gt; (plus dozens of plugins), &lt;a href="https://pypi.org/project/isort/" rel="noopener noreferrer"&gt;isort&lt;/a&gt;, &lt;a href="https://pypi.org/project/pydocstyle/" rel="noopener noreferrer"&gt;pydocstyle&lt;/a&gt;, &lt;a href="https://github.com/asottile/yesqa" rel="noopener noreferrer"&gt;yesqa&lt;/a&gt;, &lt;a href="https://pypi.org/project/eradicate/" rel="noopener noreferrer"&gt;eradicate&lt;/a&gt;, &lt;a href="https://pypi.org/project/pyupgrade/" rel="noopener noreferrer"&gt;pyupgrade&lt;/a&gt;, and &lt;a href="https://pypi.org/project/autoflake/" rel="noopener noreferrer"&gt;autoflake&lt;/a&gt;, all while executing tens or hundreds of times faster than any individual tool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm not going to replace isort and Flake8 for the purpose of this tutorial, but I will add ruff above those two to see it's performance.&lt;/p&gt;

&lt;p&gt;Let's add the following block to the pre-commit config file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/charliermarsh/ruff-pre-commit&lt;/span&gt;
  &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;v0.0.260'&lt;/span&gt;
  &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruff&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will also add the following configuration to the &lt;code&gt;pyproject.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[tool.ruff]&lt;/span&gt;
&lt;span class="py"&gt;line-length&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;, but there are a ton of other things you can configure. Check out the README for that.&lt;/p&gt;

&lt;p&gt;Now, let's run the &lt;code&gt;poetry run pre-commit run --all-files&lt;/code&gt; and see what happens. &lt;/p&gt;

&lt;p&gt;I got the same error as in the flake8 about the long HTML lines in the utils.py. The syntax for ignoring error is the same as in Flake8. The only difference is that here I had to add "# noqa: E501" at the end of a multi-line string, as opposed to the end the line. Once added at the end of the string I can remove &lt;code&gt;noqa&lt;/code&gt; comments on lines 16 &amp;amp; 17. I personally think that looks nicer. &lt;/p&gt;

&lt;p&gt;That's it. As easy as that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Aaaah, it's hard to explain the joy I get from seeing all those "Passed" messages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First of all, green is a nice color to look at.&lt;/li&gt;
&lt;li&gt;Second, I get to sleep knowing that my code quality is safe 👍 which is useful both for team and individual projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In conclusion, here is what we did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install pre-commit as a dev dependency in you poetry project.&lt;/li&gt;
&lt;li&gt;Installed a bunch of pre-commit hooks to the pre-commit config file.&lt;/li&gt;
&lt;li&gt;Configured the behavior of new hooks through &lt;code&gt;pyproject.toml&lt;/code&gt; configurations or through rc file configurations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Can't believe it took more than 3000 words to go over these 3 bullet points 🤷‍♂️. If you made it to here, a salute you 🖖, you are an incredible human being with a ton of patience and focus! You will do good in life.&lt;/p&gt;

&lt;p&gt;If you have any questions or comments, please them leave below.&lt;/p&gt;

</description>
      <category>django</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Version Control your Django project</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Fri, 05 Aug 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/rasulkireev/how-to-version-control-your-django-project-4bj7</link>
      <guid>https://dev.to/rasulkireev/how-to-version-control-your-django-project-4bj7</guid>
      <description>&lt;p&gt;In the previous post, we have gone through the process of &lt;a href="https://builtwithdjango.com/blog/basic-django-setup" rel="noopener noreferrer"&gt;setting up a basic Django project&lt;/a&gt;. In this post, we will be talking about version control and the best practices when it comes to Django projects.&lt;/p&gt;

&lt;p&gt;TL;DR use the &lt;a href="https://gist.github.com/rasulkireev/1412ab0c3585ab8ffa50764e68f2d6d7" rel="noopener noreferrer"&gt;following .gitignore&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm not going to be teaching you git in this post. I'm going to assume that you have git installed on your computer and you have a Github account. If you haven't worked with git before I recommend you check out &lt;a href="https://phoenixnap.com/kb/how-to-use-git" rel="noopener noreferrer"&gt;this post&lt;/a&gt;, it helped me when I was learning, but really there are a &lt;a href="https://duckduckgo.com/?q=how+to+git&amp;amp;ia=web" rel="noopener noreferrer"&gt;ton of other awesome posts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, that said, this post is aimed toward beginners when it comes to version controlling Django projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Why is it important to dedicate an entire post on how to version control your Django project?&lt;/p&gt;

&lt;p&gt;When I was starting out I was just doing stuff and not using tutorials. I was silly, unlike you! I ended up putting secret information to the public. For example, I was using AWS to host images, and accidentally put my secret key on Github. I was contacted by the Amazon team and was told to delete it and immediately create a new one so that some bad actors would use it maliciously. I almost sh*t my pants. I don't want this to happen to you!&lt;/p&gt;

&lt;p&gt;Another important point is that eventually (in the next post) we are going to be creating a SQLite database and storing user information on it. We don't want to expose that either.&lt;/p&gt;

&lt;p&gt;So, now that you understand the importance of good practices when it comes to version control we can begin.&lt;/p&gt;

&lt;p&gt;The good news is that it actually is not so hard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beginning of History
&lt;/h2&gt;

&lt;p&gt;After you finished the previous post, you should have a functional code. Make sure everything works by running &lt;code&gt;poetry run python manage.py runserver&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's start by creating a repo for your project on &lt;a href="https://github.com" rel="noopener noreferrer"&gt;Github&lt;/a&gt;. If you head over to &lt;a href="https://github.com/new" rel="noopener noreferrer"&gt;https://github.com/new&lt;/a&gt; you will be prompted for some info.&lt;/p&gt;

&lt;p&gt;Give your repo a name and press "Create repository". No need to change anything else.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: use kebab case for the name: something-like-that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you've done that you will see a convenient list of instructions on Github:&lt;br&gt;
&lt;a href="https://media2.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%2F5f7l889fyvg6vx0b9olh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5f7l889fyvg6vx0b9olh.png" alt="New repo github instructions" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We don't need the first line, since we already have some files.&lt;/p&gt;

&lt;p&gt;We do however need to run &lt;code&gt;git init&lt;/code&gt;  in our terminal (hopefully in an integrated VS Code terminal) to start the version control history. Once you run &lt;code&gt;git init&lt;/code&gt; you should see a couple of changes.&lt;/p&gt;

&lt;p&gt;First is the terminal itself will show the branch you are on:&lt;br&gt;
&lt;a href="https://media2.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%2Ftliwgtrglcv5kwocui5t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftliwgtrglcv5kwocui5t.png" alt="Terminal after running git init" width="600" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Second is the File Explorer, all files should have turned green meaning that they are new files in our repo, they haven't appeared before in our history. If files had existed but were changed, they would have turned yellow.&lt;br&gt;
&lt;a href="https://media2.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%2Fvqk37j1bpa2r7g77d226.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvqk37j1bpa2r7g77d226.png" alt="File Explorer after git init" width="213" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ignoring secrets
&lt;/h2&gt;

&lt;p&gt;Awesome! Now, before adding all our files to our repo history let's create a &lt;code&gt;.gitignore&lt;/code&gt; file in which we will list all the files and folders that we don't want to end up in the history.&lt;/p&gt;

&lt;p&gt;So, create &lt;code&gt;.gitignore&lt;/code&gt; file at the root of your project. Copy the content from the &lt;a href="https://gist.github.com/rasulkireev/1412ab0c3585ab8ffa50764e68f2d6d7" rel="noopener noreferrer"&gt;following gist&lt;/a&gt; and paste it into the &lt;code&gt;.gitignore&lt;/code&gt; file. Now files and folders that match the Regex in &lt;code&gt;.gitignore&lt;/code&gt;, will not be version controlled.&lt;/p&gt;

&lt;p&gt;You should care about most of them. Here are the important ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;.env&lt;/code&gt;. We will be storing our secrets in this file, so we don't want them to end up on Github.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;*.sqlite3&lt;/code&gt;. We don't want any database to end up on Github either.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;node_modules/&lt;/code&gt; this is where all Javascript packages will be stored, once we get there. &lt;code&gt;node_modules/&lt;/code&gt; are notoriously large directories, so we don't want them to be on Github as they will slow up all actions immensely.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;media/&lt;/code&gt; when we are going to work locally, some images that we will upload into our database will end up in the media folder. Since Github has some rules regarding how much space you can take, we don't want any images to end up there, as they tend to be heavy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;other than that you shouldn't worry too much about other things, at least for now.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Steps
&lt;/h2&gt;

&lt;p&gt;Now we can run other commands provided by Github. In your terminal run:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;git add --all&lt;/code&gt; to add all the files (except the ones in &lt;code&gt;.gitignore&lt;/code&gt;) to version control history.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git commit -m "first commit"&lt;/code&gt;, to "commit" the changes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git branch -M main&lt;/code&gt; to rename the main branch. New standard.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git remote add origin git@github.com:{your username}/{your project name}.git&lt;/code&gt;. Use the command provided by Github.&lt;/li&gt;
&lt;li&gt;Finally, run &lt;code&gt;git push -u origin main&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you didn't run into any issues, then you can try reloading the Github page and seeing if the files have been added to the repo.&lt;/p&gt;

&lt;p&gt;If all is good, then congratulations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we have created a repo and committed our files to it. This will help us keep track of our code in future posts.&lt;/p&gt;




&lt;p&gt;Originally posted on &lt;a href="https://builtwithdjango.com/blog/django-version-control" rel="noopener noreferrer"&gt;Built with Django&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>git</category>
      <category>versioncontrol</category>
    </item>
    <item>
      <title>Setting up a basic Django project with Poetry</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Fri, 28 Jan 2022 16:58:12 +0000</pubDate>
      <link>https://dev.to/rasulkireev/setting-up-a-basic-django-project-with-poetry-lhc</link>
      <guid>https://dev.to/rasulkireev/setting-up-a-basic-django-project-with-poetry-lhc</guid>
      <description>&lt;p&gt;In this tutorial, we will go through the process of setting up the most basic Django project that we will be using for other posts and tutorials.&lt;/p&gt;

&lt;p&gt;We will be using &lt;a href="https://github.com/pyenv/pyenv" rel="noopener noreferrer"&gt;Pyenv&lt;/a&gt; and &lt;a href="https://python-poetry.org/docs/" rel="noopener noreferrer"&gt;Poetry&lt;/a&gt; to manage the virtual environment and dependencies for your project.&lt;/p&gt;

&lt;p&gt;Unfortunately, some things that I'm going through don't work exactly the same for Windows users (e.g. Pyenv). So, if you are following on a Windows machine you might run into some issues. If you do, try messaging me on Twitter, I'll try to do my best to help you.&lt;/p&gt;

&lt;p&gt;During this tutorial, it might seem like too many things are going on things are becoming confusing. I'll try to separate it into manageable chunks that are easy to understand. And don't worry, some of the things in this tutorial only have to be done once.&lt;/p&gt;

&lt;p&gt;The method of setting up repos that I propose can differ from others, but I really enjoy it. It helps me keep all the versions and virtual environments neat and tidy, which reduces the amount errors and bugs in the future. And if you stay with me till the end of the tutorial, hopefully, I can convert you to a Poetry person too :).&lt;/p&gt;

&lt;p&gt;So, let's get the party started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pyenv
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We are going to use brew to install Pyenv. If you don't have brew installed on your Mac, run the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;now let's install pyenv:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew update
brew &lt;span class="nb"&gt;install &lt;/span&gt;pyenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If this didn't work for you try &lt;a href="https://github.com/pyenv/pyenv#homebrew-in-macos" rel="noopener noreferrer"&gt;these fixes&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you are on a Windows machine, follow the &lt;a href="https://github.com/pyenv/pyenv#windows" rel="noopener noreferrer"&gt;following instruction&lt;/a&gt; to install pyenv.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;to test if this was installed correctly try running this in your terminal:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pyenv versions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;we are going to be using Python version 3.9.9 in our tutorial, so let's get that installed with the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pyenv &lt;span class="nb"&gt;install &lt;/span&gt;3.9.9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your terminal will start giving you some outputs. Wait for a minute or two until the download and installation are complete. This is everything we are going to cover regarding pyenv, we don't need to know more for the purposes of this tutorial.&lt;/p&gt;

&lt;h3&gt;
  
  
  Poetry
&lt;/h3&gt;

&lt;p&gt;If you have Poetry installed you can skip this step.&lt;/p&gt;

&lt;p&gt;So, let's first install Poetry.  You can do that by running the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are on Windows you would run the following in your Powershell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Invoke-WebRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-UseBasicParsing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The good news is that you have to do it once. To test that everything went smoothly, try running the following in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up the Environment
&lt;/h2&gt;

&lt;p&gt;Alright, we are now ready to start. Here is what you want to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open up your terminal, &lt;code&gt;cd&lt;/code&gt; into the directory that you use to store all your code. For me it is:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then create a new directory for your project. I'm going to call mine "basic_django", but you can call it whatever else you want:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;basic_django &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;basic_django
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now, I suggest you open up your VS Code and open your newly-created directory. Alternatively, you can run this command in your terminal:
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Let's use pyenv to explicitly say what Python version we will be using in that repo. For that, run the following in your terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pyenv &lt;span class="nb"&gt;local &lt;/span&gt;3.9.9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a file named &lt;code&gt;.python-version&lt;/code&gt; created in your folder. That's good.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now were are going to initialize Poetry project with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You will be prompted to confirm a couple of settings. You can just skip the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Package name &lt;span class="o"&gt;[&lt;/span&gt;basic_django]:
Version &lt;span class="o"&gt;[&lt;/span&gt;0.1.0]:
Description &lt;span class="o"&gt;[]&lt;/span&gt;:
Author &lt;span class="o"&gt;[&lt;/span&gt;Rasul Kireev &amp;lt;rasul.kireev@guycarp.com&amp;gt;, n to skip]:
License &lt;span class="o"&gt;[]&lt;/span&gt;:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;When you get to the following line type in "^3.8" and press Enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Compatible Python versions &lt;span class="o"&gt;[&lt;/span&gt;^3.7]: ^3.9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason we do that is that the latest Django version requires the use of Python Version 3.8 and up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you get to these prompts, type in "no". We are going to add our own dependencies later on:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Would you like to define your main dependencies interactively? (yes/no) [yes]

Would you like to define your development dependencies interactively? (yes/no) [yes]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the end, you would have gone through the process that looked something like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="err"&gt;This&lt;/span&gt; &lt;span class="err"&gt;command&lt;/span&gt; &lt;span class="err"&gt;will&lt;/span&gt; &lt;span class="err"&gt;guide&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;through&lt;/span&gt; &lt;span class="err"&gt;creating&lt;/span&gt; &lt;span class="err"&gt;your&lt;/span&gt; &lt;span class="err"&gt;pyproject.toml&lt;/span&gt; &lt;span class="err"&gt;config.&lt;/span&gt;

&lt;span class="err"&gt;Package&lt;/span&gt; &lt;span class="err"&gt;name&lt;/span&gt; &lt;span class="nn"&gt;[basic_django]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="err"&gt;Version&lt;/span&gt; &lt;span class="nn"&gt;[0.1.0]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="err"&gt;Description&lt;/span&gt; &lt;span class="nn"&gt;[]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="err"&gt;Author&lt;/span&gt; &lt;span class="nn"&gt;[Rasul Kireev &amp;lt;rasul.kireev@guycarp.com&amp;gt;, n to skip]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="err"&gt;License&lt;/span&gt; &lt;span class="nn"&gt;[]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="err"&gt;Compatible&lt;/span&gt; &lt;span class="err"&gt;Python&lt;/span&gt; &lt;span class="err"&gt;versions&lt;/span&gt; &lt;span class="nn"&gt;[^3.7]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;^3.9&lt;/span&gt;

&lt;span class="err"&gt;Would&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;like&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;define&lt;/span&gt; &lt;span class="err"&gt;your&lt;/span&gt; &lt;span class="err"&gt;main&lt;/span&gt; &lt;span class="err"&gt;dependencies&lt;/span&gt; &lt;span class="err"&gt;interactively?&lt;/span&gt; &lt;span class="err"&gt;(yes/no)&lt;/span&gt; &lt;span class="nn"&gt;[yes]&lt;/span&gt; &lt;span class="err"&gt;no&lt;/span&gt;
&lt;span class="err"&gt;Would&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;like&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;define&lt;/span&gt; &lt;span class="err"&gt;your&lt;/span&gt; &lt;span class="err"&gt;development&lt;/span&gt; &lt;span class="err"&gt;dependencies&lt;/span&gt; &lt;span class="err"&gt;interactively?&lt;/span&gt; &lt;span class="err"&gt;(yes/no)&lt;/span&gt; &lt;span class="nn"&gt;[yes]&lt;/span&gt; &lt;span class="err"&gt;no&lt;/span&gt;
&lt;span class="err"&gt;Generated&lt;/span&gt; &lt;span class="err"&gt;file&lt;/span&gt;

&lt;span class="nn"&gt;[tool.poetry]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"basic_django"&lt;/span&gt;
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1.0"&lt;/span&gt;
&lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
&lt;span class="py"&gt;authors&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Rasul Kireev &amp;lt;rasul.kireev@guycarp.com&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[tool.poetry.dependencies]&lt;/span&gt;
&lt;span class="py"&gt;python&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^3.7"&lt;/span&gt;

&lt;span class="nn"&gt;[tool.poetry.dev-dependencies]&lt;/span&gt;

&lt;span class="nn"&gt;[build-system]&lt;/span&gt;
&lt;span class="py"&gt;requires&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;["poetry-core&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="s"&gt;"]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="py"&gt;build-backend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"poetry.core.masonry.api"&lt;/span&gt;


&lt;span class="err"&gt;Do&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;confirm&lt;/span&gt; &lt;span class="err"&gt;generation?&lt;/span&gt; &lt;span class="err"&gt;(yes/no)&lt;/span&gt; &lt;span class="nn"&gt;[yes]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now let's add the Django dependency and try running the test server. So, to add a dependency in a Poetry project you just simply do:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry add Django
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;After this command finished running let's see what we have. You should see two files:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pyproject.toml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;poetry.lock&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;poetry.lock&lt;/code&gt; is a file that keeps all the project dependencies nice and constant so that if other people want to use your project, they will be able to install the exact same versions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pyproject.toml&lt;/code&gt; is a nice visual file that lists all the project dependencies. In future posts, we will be using it to give our project configurations. Here is what we have in the &lt;code&gt;pyproject.toml&lt;/code&gt; file right now (you should see something very similar):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[tool.poetry]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"basic_django"&lt;/span&gt;
&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1.0"&lt;/span&gt;
&lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
&lt;span class="py"&gt;authors&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Rasul Kireev &amp;lt;rasul.kireev@guycarp.com&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[tool.poetry.dependencies]&lt;/span&gt;
&lt;span class="py"&gt;python&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^3.9"&lt;/span&gt;
&lt;span class="py"&gt;Django&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^4.0.1"&lt;/span&gt;

&lt;span class="nn"&gt;[tool.poetry.dev-dependencies]&lt;/span&gt;

&lt;span class="nn"&gt;[build-system]&lt;/span&gt;
&lt;span class="py"&gt;requires&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;["poetry-core&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="s"&gt;"]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="py"&gt;build-backend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"poetry.core.masonry.api"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that we are using the latest Django version, 4.0.1. If you want to use some other Django version, you can specify that when adding that dependency, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry add &lt;span class="s2"&gt;"Django&amp;gt;=3.2.4"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to change the version of the file retroactively, you can manually change the value in the &lt;code&gt;pyproject.toml&lt;/code&gt; file and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Let's initiate a Django project with the Django admin command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry run django-admin.py startproject basic_django &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Ok, if you have never used poetry before this is important. In the command above can see I'm using &lt;code&gt;poetry run&lt;/code&gt;. I'm adding this so that poetry runs the django-admin command for me from the virtual environment that will have all the dependencies that we specified earlier. If you don't want to keep typing &lt;code&gt;poetry run&lt;/code&gt; for every command, you can simply run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then use commands as you usually would. However, I don't recommend that, since if you have multiple projects open, virtual environments might not work nicely with each other. I suggest explicitly running python commands with &lt;code&gt;poetry run …&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Second thing to note is the "." at the end of the command. This tells us that we have a parent directory already created, no need to do that for us.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now in your File Explorer you should have the following:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;basic_django/ (This will be different for you)
manage.py      
poetry.lock    
pyproject.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Finally to test that everything is set up as it should be let's run the local server:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry run python manage.py runserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tip: you should not be writing these commands all the time. If you have already run one of these commands previously you can press the ⬆️ key on your keyboard, while in the terminal and it will show the previous command you run, so that you don't have to write it down again.&lt;/p&gt;

&lt;p&gt;Another tip: This is related. If you start typing "poetry run" in your terminal and then start pressing the ⬆️ key, your terminal will show only commands that have started with these keywords.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You will see something 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;Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
January 27, 2022 - 17:25:15
Django version 4.0.1, using settings 'basic_django.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is good! We can go to our browser and go to the URL specified in the output (&lt;a href="http://127.0.0.1:8000/" rel="noopener noreferrer"&gt;http://127.0.0.1:8000/&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You should see a Django welcome screen.&lt;/li&gt;
&lt;li&gt;Notice the following line in the terminal output: "You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions." This is because we haven't run any migrations, and that's by design. We will not run any migrations until we have created a custom user model. If you don't anticipate your app to have a user, then don't worry about this.&lt;/li&gt;
&lt;li&gt;I did not yet write a guide on how to create a Custom User Model, so will refer you to the best resource I know and that is &lt;a href="https://learndjango.com/tutorials/django-custom-user-model" rel="noopener noreferrer"&gt;Will Vincent's blog&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding Static Pages
&lt;/h2&gt;

&lt;p&gt;Before we create models, databases, and other fun stuff let's first create some static pages. For that, we are going to create a "pages" application. I got this approach from Will Vincent, and have been using it for a long time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new application with the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry run python manage.py startapp pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a new folder pop up in your Code Editor named "pages" 👍.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Head over to the &lt;code&gt;urls.py&lt;/code&gt; file in the &lt;code&gt;basic_django&lt;/code&gt; directory (remember for you the name of the "core" directory is different, whatever you chose when setting up the project) and add the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# basic_django/urls.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="c1"&gt;# new
&lt;/span&gt;
&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;admin/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pages.urls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="c1"&gt;# new
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we are doing here is we are adding a namespace to our site, basically saying that all the pages that will be created under the pages app will be at the root of the URL.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Head over to the &lt;code&gt;setting.py&lt;/code&gt; in the root folder (&lt;code&gt;basic_django&lt;/code&gt; for me) and search for the TEMPLATES variable and replace the &lt;code&gt;DIRS&lt;/code&gt; list to be this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# basic_django/settings.py
&lt;/span&gt;&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;TEMPLATES&lt;/span&gt; &lt;span class="o"&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;BACKEND&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;django.template.backends.django.DjangoTemplates&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;DIRS&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="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE_DIR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;templates&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))],&lt;/span&gt; &lt;span class="c1"&gt;# new
&lt;/span&gt;        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;APP_DIRS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;OPTIONS&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;context_processors&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;django.template.context_processors.debug&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;django.template.context_processors.request&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;django.contrib.auth.context_processors.auth&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;django.contrib.messages.context_processors.messages&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;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will tell our Django application that all templates are under the templates folder.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, let's actually create the &lt;code&gt;templates&lt;/code&gt; directory in the root folder. You can do that in the VS Code UI, or with the &lt;code&gt;mkdir&lt;/code&gt; command. Just make sure that you are in the root folder.&lt;/li&gt;
&lt;li&gt;Inside the &lt;code&gt;templates&lt;/code&gt; folder create a &lt;code&gt;base.html&lt;/code&gt; file. Inside that html file add the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"IE=edge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Basic Django Project&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

  {% block content %}
  {% endblock %}

&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This template will be used as a base for all other templates in our project. Here, we can add the header, footer, and other components that will be present on each page of the site.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, let's create a template for the home page. Create a &lt;code&gt;pages&lt;/code&gt; folder, under &lt;code&gt;templates&lt;/code&gt; folder. And inside that folder create a &lt;code&gt;home.html&lt;/code&gt; file and add the following to it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{% extends 'base.html' %}

{% block content %}
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Helllloooooo!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
{% endblock content %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here were are extending the base template and adding a header to it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: If you are doing this for the first time, this might seem like a hard, long, and annoying task. But once you get the hang of it, things become to make sense and fall into their places.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now the last two pieces to finish the proper setup of our Django project are URLs and Views.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's start with views. Go to the &lt;code&gt;views.py&lt;/code&gt; file under the &lt;code&gt;pages&lt;/code&gt; folder and add the following code:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# pages/views.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TemplateView&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TemplateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;template_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;pages/home.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And let's create a URL for that HomeView. Create a &lt;code&gt;urls.py&lt;/code&gt; in the &lt;code&gt;pages&lt;/code&gt; folder and add the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# pages/urls.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HomeView&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HomeView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;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;home&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now if you start the dev server with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry run python manage.py runserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you should see the word "Helllllooooo!".&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations! You are done with the Django Project Setup. After all of this you should have a directory looking something 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;.
├── basic_django
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-39.pyc
│   │   ├── settings.cpython-39.pyc
│   │   ├── urls.cpython-39.pyc
│   │   └── wsgi.cpython-39.pyc
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
├── pages
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-39.pyc
│   │   ├── urls.cpython-39.pyc
│   │   └── views.cpython-39.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── poetry.lock
├── pyproject.toml
└── templates
    ├── base.html
    └── pages
        └── home.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After finishing this tutorial you should know how to set up a Django Project with Poetry and Pyenv. In the future, I'm going to be writing a guide on how to integrate various tools into your Django Project, and having this neat setup will help a lot.&lt;/p&gt;

&lt;p&gt;If you run into any issues or have any questions, feel free to message me on &lt;a href="https://twitter.com/builtwithdjango" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Managing a Django Project with Poetry</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Sat, 31 Oct 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/rasulkireev/managing-a-django-project-with-poetry-cnm</link>
      <guid>https://dev.to/rasulkireev/managing-a-django-project-with-poetry-cnm</guid>
      <description>&lt;p&gt;Poetry is relatively new packaging and dependency manager. It makes it very easy to upload libraries to &lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;, manage dependencies visually, and has a couple of handy features. Today, I'm not going to do a deep dive into how &lt;a href="https://python-poetry.org/" rel="noopener noreferrer"&gt;Poetry&lt;/a&gt; works and all its features. Today I just want to focus on configuring a &lt;a href="https://www.djangoproject.com/" rel="noopener noreferrer"&gt;Django&lt;/a&gt; project.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Install Poetry
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Create a Directory for you Django Project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;django_poetry_example &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;ls &lt;/span&gt;django_poetry_example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Initiate a Poetry Project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;poetry init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be asked to confirm the information about your project. You can skip through most of it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frasulkireev.com%2Fassets%2Fstatic%2Fpoetry_init.cd61fdf.02d3f24e444ee33cc2ed0480e0f26c9f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frasulkireev.com%2Fassets%2Fstatic%2Fpoetry_init.cd61fdf.02d3f24e444ee33cc2ed0480e0f26c9f.png" alt="Poetry Init" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Add the Necessary Dependencies
&lt;/h2&gt;

&lt;p&gt;Run &lt;code&gt;poetry add django&lt;/code&gt;. Poetry will add django to the pyproject.toml file under the dependencies section. A virtual environment will also be created for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Start you Django Project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;django-admin startproject django_poetry_example &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Working on your Django Project
&lt;/h2&gt;

&lt;p&gt;When you need to run any python function (for example, &lt;code&gt;python manage.py createsuperuser&lt;/code&gt;) you have two options.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You can leverage poetry run, which will run against the current project's dependencies. The command will be this:&lt;br&gt;
&lt;code&gt;poetry run python manage.py createsuperuser&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can activate the virtual environment with a poetry shell command. Now you can run python commands, as is. They will be run with dependencies you have installed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Bonus. Export dependencies to a requirements.txt
&lt;/h2&gt;

&lt;p&gt;If you need to have the requirements.txt file with all the dependencies, you can run poetry export -f requirements.txt --output requirements.txt. If you have configured a CI/CD job that auto deploys your project, you can add this function as a step, which will generate the updated version on each update.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus II. Video
&lt;/h2&gt;

&lt;p&gt;If you prefer a more visual approach, I have made a video that shows how to start a Django project with Poetry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/-c8DASfFNZM" rel="noopener noreferrer"&gt;https://youtu.be/-c8DASfFNZM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any feedback, please let me know on &lt;a href="https://twitter.com/rasulkireev/status/1322499651732385792" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Sponsorware is picking up</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Tue, 18 Aug 2020 15:38:47 +0000</pubDate>
      <link>https://dev.to/rasulkireev/sponsorware-is-picking-up-2mn6</link>
      <guid>https://dev.to/rasulkireev/sponsorware-is-picking-up-2mn6</guid>
      <description>&lt;p&gt;A couple of months ago, I signed up for &lt;a href="https://calebporzio.com/" rel="noopener noreferrer"&gt;Caleb Porzio&lt;/a&gt;'s &lt;a href="https://learn-vscode.com/" rel="noopener noreferrer"&gt;newsletter about VS Code&lt;/a&gt;. I then rediscovered Caleb through his post on &lt;a href="https://calebporzio.com/i-just-hit-dollar-100000yr-on-github-sponsors-heres-how-i-did-it" rel="noopener noreferrer"&gt;hitting $100k/y through Github Sponsors&lt;/a&gt;. This post made quite the round across the internet, after all, that's the dream, right?&lt;/p&gt;

&lt;p&gt;In this post, he said that one of the spikes was due to the &lt;a href="https://calebporzio.com/sponsorware" rel="noopener noreferrer"&gt;Sponsorware&lt;/a&gt;. It's not an app or anything, it's just an idea. The idea is that you only let your supporters use your "open-source" work until you reach a certain number of sponsors. Once you reach this level, you make the repo public. That's pretty genius.&lt;/p&gt;

&lt;p&gt;I'm very intrigued by this idea and have decided to give it a go. I have applied for the &lt;a href="https://github.com/sponsors/" rel="noopener noreferrer"&gt;Github Sponsors&lt;/a&gt; program. The process is very straight forward. If you do any open-source work, I suggest you apply as well, there is no harm. If you get in, try this Sponsorware thing, I think the future of open-source is very bright if more people adopt this strategy. If I don't get in, no worries, I'll just keep working on my open-source projects until I can get in.&lt;/p&gt;

&lt;p&gt;I don't have a huge following my work, but I hope this post will spread. I think that this way of working is very healthy for the developer and for the community alike. I really hope this picks up.&lt;/p&gt;

&lt;p&gt;Thanks for reading, have a wonderful day!&lt;/p&gt;

&lt;p&gt;You can reply on &lt;a href="https://twitter.com/rasulkireev/status/1295740529012092929" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. Your reply will be displayed here, also, thanks to the &lt;a href="https://indieweb.org/webmention" rel="noopener noreferrer"&gt;webentions&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>Multiple Graphql Queries on a Single Page with Gridsome</title>
      <dc:creator>Rasul Kireev</dc:creator>
      <pubDate>Thu, 23 Jul 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/rasulkireev/multiple-graphql-queries-on-a-single-page-with-gridsome-5368</link>
      <guid>https://dev.to/rasulkireev/multiple-graphql-queries-on-a-single-page-with-gridsome-5368</guid>
      <description>&lt;p&gt;Ever wonder how include multiple queries on the same page, when using Gridsome? Well, this is how.&lt;/p&gt;

&lt;p&gt;Let's say you have the following queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// query details about the current blog post &lt;/span&gt;
&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nc"&gt;Post &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;post&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;post &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;
    &lt;span class="nf"&gt;date &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MMMM D, Y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt;
    &lt;span class="nx"&gt;path&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// query to pull all the webmentions on a specific post&lt;/span&gt;
&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;mentions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;allWebMention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;wmTarget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$path&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;span class="nx"&gt;edges&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;wmId&lt;/span&gt;
          &lt;span class="nx"&gt;wmProperty&lt;/span&gt;
          &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;text&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;author&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;name&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;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;The question is: How do you get both of those queries in your &lt;code&gt;Post.vue&lt;/code&gt; template?&lt;/p&gt;

&lt;p&gt;I was going to give you all the options that I tried before making this work, but that would be the waste of your time. So here is he working version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nc"&gt;Post &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;post&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;post &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;
    &lt;span class="nf"&gt;date &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MMMM D, Y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt;
    &lt;span class="nx"&gt;path&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nl"&gt;mentions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;allWebMention &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;wmTarget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$path&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;span class="nx"&gt;totalCount&lt;/span&gt;
    &lt;span class="nx"&gt;edges&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;wmId&lt;/span&gt;
        &lt;span class="nx"&gt;wmProperty&lt;/span&gt;
        &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;text&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;author&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;name&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;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/page-query&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can access these queries like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;{{ $page.post.title }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; 
&lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"mention in $page.mentions.edges"&lt;/span&gt;
&lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"mention.node.wmId"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ mention.node.wmProperty }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ mention.node.content.text }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have any thougths, comments or questions please let me know on &lt;a href="https://twitter.com/rasulkireev/status/1286433227960463360" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>gridsome</category>
      <category>graphql</category>
      <category>html</category>
    </item>
  </channel>
</rss>
