Author: saqibkhan

  • Apache Setup

    So far, in our examples, we have used the Django dev web server. But this server is just for testing and is not fit for production environment. Once in production, you need a real server like Apache, Nginx, etc. Let’s discuss Apache in this chapter.

    Serving Django applications via Apache is done by using mod_wsgi. So the first thing is to make sure you have Apache and mod_wsgi installed. Remember, when we created our project and we looked at the project structure, it looked like −

    myproject/
       manage.py
       myproject/
    
      __init__.py
      settings.py
      urls.py
      wsgi.py

    The wsgi.py file is the one taking care of the link between Django and Apache.

    Let’s say we want to share our project (myproject) with Apache. We just need to set Apache to access our folder. Assume we put our myproject folder in the default “/var/www/html”. At this stage, accessing the project will be done via 127.0.0.1/myproject. This will result in Apache just listing the folder as shown in the following snapshot.

    Django Apache Setup

    As seen, Apache is not handling Django stuff. For this to be taken care of, we need to configure Apache in httpd.conf. So open the httpd.conf and add the following line −

    WSGIScriptAlias / /var/www/html/myproject/myproject/wsgi.py
    WSGIPythonPath /var/www/html/myproject/
    
    <Directory /var/www/html/myproject/>
       <Files wsgi.py>
    
      Order deny,allow
      Allow from all
    </Files> </Directory>

    If you can access the login page as 127.0.0.1/myapp/connection, you will get to see the following page −

    Login Page
  • Open Source:

    Django is an open-source framework, which means it’s free to use and can be modified by anyone. This encourages a collaborative community that continuously improves the framework.

  • Integration with Modern Tech Stacks

    • GraphQL and Other APIs: Django is increasingly being used alongside modern technologies like GraphQL, React, and Vue.js, allowing developers to create dynamic, responsive applications.
  • Future Directions

    • Continuous Evolution: Django continues to evolve, with an active development team and community focused on enhancing performance, security, and features, ensuring it remains relevant in a rapidly changing tech landscape.
  • Focus on Documentation

    • Comprehensive Guides: Django’s documentation is frequently praised for its thoroughness, making it accessible for both beginners and experienced developers. The community actively contributes to keeping it updated.
  • File Uploading

    It is generally useful for a web app to be able to upload files (profile picture, songs, pdf, words…..). Let’s discuss how to upload files in this chapter.

    Uploading an Image

    Before starting to play with an image, make sure you have the Python Image Library (PIL) installed. Now to illustrate uploading an image, let’s create a profile form, in our myapp/forms.py −

    #-*- coding: utf-8 -*-
    from django import forms
    
    class ProfileForm(forms.Form):
       name = forms.CharField(max_length = 100)
       picture = forms.ImageFields()

    As you can see, the main difference here is just the forms.ImageField. ImageField will make sure the uploaded file is an image. If not, the form validation will fail.

    Now let’s create a “Profile” model to save our uploaded profile. This is done in myapp/models.py −

    from django.db import models
    
    class Profile(models.Model):
       name = models.CharField(max_length = 50)
       picture = models.ImageField(upload_to = 'pictures')
    
       class Meta:
    
      db_table = "profile"</code></pre>

    As you can see for the model, the ImageField takes a compulsory argument: upload_to. This represents the place on the hard drive where your images will be saved. Note that the parameter will be added to the MEDIA_ROOT option defined in your settings.py file.

    Now that we have the Form and the Model, let's create the view, in myapp/views.py −

    #-*- coding: utf-8 -*-
    from myapp.forms import ProfileForm
    from myapp.models import Profile
    
    def SaveProfile(request):
       saved = False
       
       if request.method == "POST":
    
      #Get the posted form
      MyProfileForm = ProfileForm(request.POST, request.FILES)
      
      if MyProfileForm.is_valid():
         profile = Profile()
         profile.name = MyProfileForm.cleaned_data&#91;"name"]
         profile.picture = MyProfileForm.cleaned_data&#91;"picture"]
         profile.save()
         saved = True
    else:
      MyProfileForm = Profileform()
    return render(request, 'saved.html', locals())

    The part not to miss is, there is a change when creating a ProfileForm, we added a second parameters: request.FILES. If not passed the form validation will fail, giving a message that says the picture is empty.

    Now, we just need the saved.html template and the profile.html template, for the form and the redirection page −

    myapp/templates/saved.html −

    <html>
       <body>
       
    
      {% if saved %}
         &lt;strong&gt;Your profile was saved.&lt;/strong&gt;
      {% endif %}
      
      {% if not saved %}
         &lt;strong&gt;Your profile was not saved.&lt;/strong&gt;
      {% endif %}
      
    </body> </html>

    myapp/templates/profile.html −

    <html>
       <body>
       
    
      &lt;form name = "form" enctype = "multipart/form-data" 
         action = "{% url "myapp.views.SaveProfile" %}" method = "POST" &gt;{% csrf_token %}
         
         &lt;div style = "max-width:470px;"&gt;
            &lt;center&gt;  
               &lt;input type = "text" style = "margin-left:20%;" 
               placeholder = "Name" name = "name" /&gt;
            &lt;/center&gt;
         &lt;/div&gt;
         &lt;br&gt;
         
         &lt;div style = "max-width:470px;"&gt;
            &lt;center&gt; 
               &lt;input type = "file" style = "margin-left:20%;" 
                  placeholder = "Picture" name = "picture" /&gt;
            &lt;/center&gt;
         &lt;/div&gt;
         &lt;br&gt;
         
         &lt;div style = "max-width:470px;"&gt;
            &lt;center&gt; 
            
               &lt;button style = "border:0px;background-color:#4285F4; margin-top:8%; 
                  height:35px; width:80%; margin-left:19%;" type = "submit" value = "Login" &gt;
                  &lt;strong&gt;Login&lt;/strong&gt;
               &lt;/button&gt;
               
            &lt;/center&gt;
         &lt;/div&gt;
         
      &lt;/form&gt;
      
    </body> </html>

    Next, we need our pair of URLs to get started: myapp/urls.py

    from django.conf.urls import patterns, url
    from django.views.generic import TemplateView
    
    urlpatterns = patterns(
       'myapp.views', url(r'^profile/',TemplateView.as_view(
    
      template_name = 'profile.html')), url(r'^saved/', 'SaveProfile', name = 'saved')
    )

    When accessing "/myapp/profile", we will get the following profile.html template rendered −

    Uploading Image

    And on form post, the saved template will be rendered −

    Form Post Template

    We have a sample for image, but if you want to upload another type of file, not just image, just replace the ImageField in both Model and Form with FileField.

  • Support for Asynchronous Programming

    • Modern Capabilities: The addition of async support in Django 3.1 marked a significant shift, allowing developers to build more performant applications that can handle concurrent requests more effectively.
  • Community Contributions and Events

    • DjangoCon: Annual conferences, such as DjangoCon, provide a platform for developers to share knowledge, showcase projects, and discuss future directions for the framework.
    • Django Girls Workshops: These workshops have played a crucial role in introducing many women to programming and web development, fostering diversity in the Django community.
  • Form Processing

    Creating forms in Django, is really similar to creating a model. Here again, we just need to inherit from Django class and the class attributes will be the form fields. Let’s add a forms.py file in myapp folder to contain our app forms. We will create a login form.

    myapp/forms.py

    #-*- coding: utf-8 -*-
    from django import forms
    
    class LoginForm(forms.Form):
       user = forms.CharField(max_length = 100)
       password = forms.CharField(widget = forms.PasswordInput())

    As seen above, the field type can take “widget” argument for html rendering; in our case, we want the password to be hidden, not displayed. Many others widget are present in Django: DateInput for dates, CheckboxInput for checkboxes, etc.

    Using Form in a View

    There are two kinds of HTTP requests, GET and POST. In Django, the request object passed as parameter to your view has an attribute called “method” where the type of the request is set, and all data passed via POST can be accessed via the request.POST dictionary.

    Let’s create a login view in our myapp/views.py −

    #-*- coding: utf-8 -*-
    from myapp.forms import LoginForm
    
    def login(request):
       username = "not logged in"
       
       if request.method == "POST":
    
      #Get the posted form
      MyLoginForm = LoginForm(request.POST)
      
      if MyLoginForm.is_valid():
         username = MyLoginForm.cleaned_data&#91;'username']
    else:
      MyLoginForm = Loginform()
    return render(request, 'loggedin.html', {"username" : username})

    The view will display the result of the login form posted through the loggedin.html. To test it, we will first need the login form template. Let’s call it login.html.

    <html>
       <body>
    
      
      &lt;form name = "form" action = "{% url "myapp.views.login" %}" 
         method = "POST" &gt;{% csrf_token %}
         
         &lt;div style = "max-width:470px;"&gt;
            &lt;center&gt; 
               &lt;input type = "text" style = "margin-left:20%;" 
                  placeholder = "Identifiant" name = "username" /&gt;
            &lt;/center&gt;
         &lt;/div&gt;
         &lt;br&gt;
         
         &lt;div style = "max-width:470px;"&gt;
            &lt;center&gt;
               &lt;input type = "password" style = "margin-left:20%;" 
                  placeholder = "password" name = "password" /&gt;
            &lt;/center&gt;
         &lt;/div&gt;
         &lt;br&gt;
         
         &lt;div style = "max-width:470px;"&gt;
            &lt;center&gt; 
            
               &lt;button style = "border:0px; background-color:#4285F4; margin-top:8%;
                  height:35px; width:80%;margin-left:19%;" type = "submit" 
                  value = "Login" &gt;
                  &lt;strong&gt;Login&lt;/strong&gt;
               &lt;/button&gt;
               
            &lt;/center&gt;
         &lt;/div&gt;
         
      &lt;/form&gt;
      
    </body> </html>

    The template will display a login form and post the result to our login view above. You have probably noticed the tag in the template, which is just to prevent Cross-site Request Forgery (CSRF) attack on your site.

    {% csrf_token %}
    

    Once we have the login template, we need the loggedin.html template that will be rendered after form treatment.

    <html>
       
       <body>
    
      You are : &lt;strong&gt;{{username}}&lt;/strong&gt;
    </body> </html>

    Now, we just need our pair of URLs to get started: myapp/urls.py

    from django.conf.urls import patterns, url
    from django.views.generic import TemplateView
    
    urlpatterns = patterns('myapp.views',
       url(r'^connection/',TemplateView.as_view(template_name = 'login.html')),
       url(r'^login/', 'login', name = 'login'))

    When accessing “/myapp/connection”, we will get the following login.html template rendered −

    Login HTML Template

    On the form post, the form is valid. In our case make sure to fill the two fields and you will get −

    Form Validation

    In case your username is polo, and you forgot the password. You will get the following message −

    Form Invalid Message

    Using Our Own Form Validation

    In the above example, when validating the form −

    MyLoginForm.is_valid()
    

    We only used Django self-form validation engine, in our case just making sure the fields are required. Now let’s try to make sure the user trying to login is present in our DB as Dreamreal entry. For this, change the myapp/forms.py to −

    #-*- coding: utf-8 -*-
    from django import forms
    from myapp.models import Dreamreal
    
    class LoginForm(forms.Form):
       user = forms.CharField(max_length = 100)
       password = forms.CharField(widget = forms.PasswordInput())
    
       def clean_message(self):
    
      username = self.cleaned_data.get("username")
      dbuser = Dreamreal.objects.filter(name = username)
      
      if not dbuser:
         raise forms.ValidationError("User does not exist in our db!")
      return username</code></pre>

    Now, after calling the "is_valid" method, we will get the correct output, only if the user is in our database. If you want to check a field of your form, just add a method starting by "clean_" then your field name to your form class. Raising a forms.ValidationError is important.

  • Django Packages and Ecosystem

    • Third-Party Packages: A rich ecosystem of packages and extensions has developed around Django, enhancing its capabilities in areas like CMS, e-commerce, and more.
    • Django Packages: The Django Packages site is a community-driven resource that lists available packages for various functionalities.