<?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: Muminur Rahman</title>
    <description>The latest articles on DEV Community by Muminur Rahman (@iammumin).</description>
    <link>https://dev.to/iammumin</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%2F56923%2F4394fabf-552f-4293-b5ac-a3e5af2ad36b.jpg</url>
      <title>DEV Community: Muminur Rahman</title>
      <link>https://dev.to/iammumin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iammumin"/>
    <language>en</language>
    <item>
      <title>Python Type Hinting : Eliminating ImportError Due to Circular Imports</title>
      <dc:creator>Muminur Rahman</dc:creator>
      <pubDate>Sat, 31 Jul 2021 06:01:20 +0000</pubDate>
      <link>https://dev.to/iammumin/python-type-hinting-eliminating-importerror-due-to-circular-imports-3ihh</link>
      <guid>https://dev.to/iammumin/python-type-hinting-eliminating-importerror-due-to-circular-imports-3ihh</guid>
      <description>&lt;p&gt;We all face sometimes &lt;code&gt;ImportError&lt;/code&gt; due to having a circular import that is occurred only for type hinting. There is a simple way to handle this kind of problem.&lt;br&gt;
Let’s take we have two files like following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#book_manager.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_new_version_of_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_book_object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&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="n"&gt;old_book_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The another file:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;library.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BookManager&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

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

&lt;/div&gt;



&lt;p&gt;These two files will work fine as we did not added any type hinting. Only the &lt;code&gt;BookManager&lt;/code&gt; is imported in &lt;code&gt;book_model.py&lt;/code&gt; file. But if we add type hint to the &lt;code&gt;create_new_version_of_book&lt;/code&gt; method from &lt;code&gt;BookManager&lt;/code&gt;, then it will be as follows:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;library.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_new_version_of_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_book_object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&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="n"&gt;old_book_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here now we will get an &lt;code&gt;ImportError&lt;/code&gt; due to circular import and we will get something like the below message when we want to run the project/files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ImportError: cannot import name 'BookManager' from partially initialized module 'library.models' (most likely due to a circular import)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The solution is using &lt;code&gt;typing.TYPE_CHECKING&lt;/code&gt; constant as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;annotations&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TYPE_CHECKING&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;TYPE_CHECKING&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;library.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_new_version_of_book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_book_object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&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="n"&gt;old_book_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Line 1:&lt;/strong&gt; We have imported annotations. &lt;code&gt;__future__.annotations&lt;/code&gt; is not default in Python now; but it will become the default in Python 3.11. For details, you have a look into PEP 563. If you don’t import it, you can use type hints as string. In our case, it will be &lt;code&gt;old_book_object: ‘Book’&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Line 3:&lt;/strong&gt; We have imported &lt;code&gt;typing.TYPE_CHECKING&lt;/code&gt; special constant. The value of the constant is always False, but set to True by any type checkers, such as Mypy. We have used the this constant to make our import conditional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Line 7–8:&lt;/strong&gt; We have imported the model with a condition, so it will only be imported when the TYPE_CHECKING variable is True.&lt;/p&gt;

&lt;p&gt;Hope, this will help. :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>How To Integrate CKEditor with Django Admin</title>
      <dc:creator>Muminur Rahman</dc:creator>
      <pubDate>Mon, 24 Feb 2020 17:27:37 +0000</pubDate>
      <link>https://dev.to/iammumin/how-to-integrate-ckeditor-with-django-admin-35e4</link>
      <guid>https://dev.to/iammumin/how-to-integrate-ckeditor-with-django-admin-35e4</guid>
      <description>&lt;p&gt;Sometimes we have to add WYSIWYG editor to an input box in the Django Admin. It is a simple and easy task but may seem tricky for newbies. So, we are going to add a WYSIWYG (which s an acronym for “What You See Is What You Get”) editor to our Django Admin.&lt;br&gt;
For this tutorial, I am assuming that we have a ProjectUpdate model where we need to integrate a WYSIWYG editor. I am using CKEditor 5 for this tutorial.&lt;/p&gt;

&lt;h1&gt;
  
  
  Add an id to Admin Textarea
&lt;/h1&gt;

&lt;p&gt;At first, we need to add id to the textarea in Django Admin so that we can find it through the id and bind it with CKEditor. For that, we will use formfield_overrides that provides a quick-and-dirty way to override some of the field options on Django admin.&lt;br&gt;
   &lt;code&gt;# myproject/admin.py&lt;br&gt;
    class ProjectUpdateAdmin(admin.ModelAdmin):&lt;br&gt;
        formfield_overrides = {&lt;br&gt;
            models.TextField: {'widget': Textarea(&lt;br&gt;
                attrs={'id': 'project_update_textarea'})}&lt;br&gt;
        }&lt;/code&gt;&lt;br&gt;
Here we have added an id &lt;strong&gt;project_update_textarea&lt;/strong&gt; to every textfield in Django admin panel of the ProjectUpdate model.&lt;/p&gt;

&lt;h1&gt;
  
  
  Add the script to base.html
&lt;/h1&gt;

&lt;p&gt;At first, make a directory named admin in your templates directory and copy the &lt;em&gt;base.html&lt;/em&gt; file there. The admin base template can be found in this path: &lt;em&gt;django/contrib/admin/templates/admin/base.html&lt;/em&gt;. After that, add these lines before the body closing tag:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
    # templates/admin/base.httemplates/admin/base.httemplates/admin/base.html&lt;br&gt;
    &amp;lt;!-- Start custom scripts for customizing admin form --&amp;gt;&lt;br&gt;
    &amp;lt;script src="{% static 'vendor/ckeditor5/ckeditor.js' %}"&amp;gt;&amp;lt;/script&amp;gt;&lt;br&gt;
    &amp;lt;script&amp;gt;&lt;br&gt;
    ClassicEditor&lt;br&gt;
         .create( document.querySelector( '#project_update_textarea' ) )&lt;br&gt;
         .catch( error =&amp;gt; {&lt;br&gt;
                console.error( error );&lt;br&gt;
            } );&lt;br&gt;
    &amp;lt;/script&amp;gt;&lt;br&gt;
    &amp;lt;!-- End custom scripts for customizing admin form --&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
I have downloaded the CKEditor package and stored in &lt;em&gt;static/vendor/ckeditor5&lt;/em&gt; directory. Hence, I have used the static tag in the script. You can use the CDN link also if you prefer.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s it. Go to your Django Admin Panel. The CKEditor should work now.&lt;/p&gt;

</description>
      <category>django</category>
    </item>
  </channel>
</rss>
