Blog | CoWhite Softwarehttp://django.cowhite.com/blog/2022-01-02T12:59:58+00:00BlogList Comprehensions vs For loops in python2022-01-02T12:59:58+00:00bhaskar/blog/author/bhaskar/http://django.cowhite.com/blog/lists-comprehensions-vs-for-loops-in-python/<p>Let us take a scenario where I want to get the list of even numbers from a given range of numbers.
We can get the list of even numbers using the for loop as shown below.</p>
<div class="codehilite"><pre>even_list = []
for i in range(10000):
if i%2 == 0:
even_list.append(i)
</pre></div>
<p>As shown in the above code, we are trying to create a list of even numbers from 0 to 9999
The same can be achieved using list comprehension in a one-line as shown below</p>
<div class="codehilite"><pre>even_list =[i for i in range(10000) if i%2==0]
</pre></div>
<p>So for creating a new list, when we compare the speed of execution in the case of for loop and list comprehension, list comprehension is two times faster than the for-loop.
The performance of the list comprehension decreases a bit with the increase in the complexity of the operation performed, but still, list comprehension manages to have better processing speed than the for-loop.
In the above example, the i%2 operation is a simple operation, so the speed of the list comprehension is 2 times better than the for-loop.
Let us take the below example</p>
<div class="codehilite"><pre>list1 = []
for i in range(10000):
list1.append((i*3)**4)
</pre></div>
<p>Here, we are multiplying every element with 3 and then the multiplication result is performed an exponentiation operation with 4 , and this is a complex operation
The equivalent list comprehension logic is shown below</p>
<div class="codehilite"><pre>list2 =[(i*3)**4 for i in range(10000)]
</pre></div>
<p>Even, in this case, the list comprehension has better performance than for loop, but it is not 2 times faster now, it is more like 1.2 times faster than for loop, so definitely the performance of the list comprehension decreases with the increase in the complexity of the operation.</p>Else clause after for and while loops in python2022-01-02T06:07:35+00:00bhaskar/blog/author/bhaskar/http://django.cowhite.com/blog/else-clause-after-for-and-while-loops-in-python/<p>Some of us are not aware of the else clause after the for and while loops in python.
Take this example</p>
<div class="codehilite"><pre>weekly_trends = {1000, 1100, 1500, 1250}
is_abnormal = False
for value in weekly_trends:
if value > 1400:
is_abnormal = True
break;
if not is_abnormal:
print("no abnormalities found")
</pre></div>
<p>The above program is maintaining a flag to check if any element has a value greater than 1400, if found, it is setting the flag is_abnormal to True, then executing the break statement. And, after the for loop, we are checking the flag and if it is not set to true, we are printing "no abnormalities found".</p>
<p>Instead of maintaining a separate flag, we can make use of the else clause after the for loop as shown below.</p>
<div class="codehilite"><pre>for value in weekly_trends:
if value > 1400:
break;
else:
print("no abnormalities found")
</pre></div>
<p>So, here, the control will come to else block, only when the break statement is not executed, and this would serve the same purpose without the additional flag logic.</p>What is Python?2021-05-23T15:20:48+00:00bhaskar/blog/author/bhaskar/http://django.cowhite.com/blog/what-is-python/<p>Python is an imperative, functional, procedural, and object-oriented programming language. Using python, we can do web development, scientific computing, data science, machine learning. Programmers are given the flexibility to choose the way they write the code in python.</p>
<h3>Imperative:</h3>
<p>They can choose the python code to be imperative if they want the code execution to be sequential that is the code execution happens in a line by line way. This sequential execution is good if the requirement of the program is supposed to know the state of the program from time to time. Also, parallel processing is not possible with the imperative style of coding.</p>
<h3>Functional:</h3>
<p>Programs can go for this functional way of writing the code by using lambda functions which adds more abstraction to the code by using minimal code, however retrieving the state of the program at a particular point of time becomes difficult because of the added abstraction.</p>
<h3>Procedural:</h3>
<p>This is more like imperative, which we discussed earlier, which means the code execution is sequential in nature. For achieving the parallel processing in the sequential execution, the code is organized in the form of blocks which we call subroutines, where the control passes from the caller to the callee, here the callee is the subroutine(block of code). Using this Procedural paradigm, parallel processing, as well as reusability, are achieved even with the imperative style of coding.</p>
<h3>ObjectOrientedProgramming(OOPS):</h3>
<p>Programs can wrap the data and the methods which manipulate the data into a single data unit by means of encapsulation. This single data unit is the definition of a real entity like bank customers, eCommerce customers, etc. With this, the programmers will be able to achieve code reusability, data abstraction, and polymorphism.</p>Difference between positional arguments and keyword arguments2021-03-26T10:46:35+00:00bhaskar/blog/author/bhaskar/http://django.cowhite.com/blog/difference-between-positional-arguments-and-keyword-arguments/<p>Difference between positional arguments and keyword arguments.</p>
<p>If you consider the below example.</p>
<div class="codehilite"><pre>def fn (a, b, c = 1): # a/b required, c optional.
return a * b + c
</pre></div>
<p>Now, the above function can be called in the below ways.</p>
<div class="codehilite"><pre>print fn (1, 2) # returns 3,
</pre></div>
<p>here arguments(1,2) are positional and we did not give the third argument, so it is defaulted to value 1.
print fn (1, 2, 3) # returns 5,
here the arguments(1,2,3) are positional.</p>
<div class="codehilite"><pre>print fn (c = 5, b = 2, a = 2) # returns 9,
</pre></div>
<p>here the arguments(c = 5, b = 2, a = 2) are keyword arguments or named arguments.</p>
<div class="codehilite"><pre>print fn (b = 2, a = 2) # returns 5,
</pre></div>
<p>here the arguments(b = 2, a = 2) are keyword or named arugments and c is defaulted to value 1 .</p>
<div class="codehilite"><pre>print fn (5, c = 2, b = 1) # returns 7,
</pre></div>
<p>here 5 is positional argument and c = 2, b = 1 are named or keyword arguments.</p>
<div class="codehilite"><pre>print fn (8, b = 0) # returns 1,
</pre></div>
<p>here 8 is positional, b=0 is named and c is defaulted to value 1.</p>Working with decorators in Flask2021-01-26T06:04:33+00:00Balaji P/blog/author/bljd369/http://django.cowhite.com/blog/working-with-decorators-in-flask-1/<h3>Decorators in Flask</h3>
<p>A decorator is a wonderful ingredient with which you can add more generic flavor to one or more functions. Using decorator, you can implement authentication, authorization, input validation, etc.</p>
<h3>Decorator usage for authentication</h3>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">wraps</span>
<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">g</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">url_for</span>
<span class="k">def</span> <span class="nf">login_required</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="nd">@wraps</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">wrap</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span> <span class="n">kwargs</span><span class="p">):</span>
<span class="sd">'''if 'logged_in' in session:</span>
<span class="sd"> return f(*args, ** kwargs)'''</span>
<span class="n">authorization</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">if</span> <span class="s">"MyToken"</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">:</span>
<span class="n">authorization</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">'MyToken'</span><span class="p">]</span>
<span class="n">user_id</span> <span class="o">=</span> <span class="n">get_from_cache</span><span class="p">(</span><span class="s">"user-token-</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">authorization</span><span class="p">)</span>
<span class="k">if</span> <span class="n">user_id</span><span class="p">:</span>
<span class="n">user_id</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
<span class="n">user_data</span> <span class="o">=</span> <span class="n">get_from_cache</span><span class="p">(</span><span class="s">"user-data-</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">user_id</span><span class="p">)</span>
<span class="k">if</span> <span class="n">user_data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">user_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">user_data</span><span class="p">)</span>
<span class="n">set_user_details_in_session</span><span class="p">(</span><span class="n">user_data</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">user_id</span> <span class="o">=</span> <span class="n">user_id</span> <span class="c">## try to understand this line</span>
<span class="n">session</span><span class="p">[</span><span class="s">'user_id'</span><span class="p">]</span> <span class="o">=</span> <span class="n">user_id</span>
<span class="n">session</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span> <span class="o">=</span> <span class="n">user_data</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span>
<span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">({</span><span class="s">"error"</span><span class="p">:</span> <span class="s">"Invalid Token"</span><span class="p">,</span> <span class="s">"status_code"</span><span class="p">:</span> <span class="mi">0</span><span class="p">}),</span> <span class="mi">400</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">({</span><span class="s">"error"</span><span class="p">:</span> <span class="s">"Invalid Token"</span><span class="p">,</span> <span class="s">"status_code"</span><span class="p">:</span> <span class="mi">0</span><span class="p">}),</span> <span class="mi">400</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">({</span><span class="s">"error"</span><span class="p">:</span> <span class="s">"Authentication failed"</span><span class="p">,</span> <span class="s">"status_code"</span><span class="p">:</span> <span class="mi">0</span><span class="p">}),</span> <span class="mi">400</span>
<span class="k">return</span> <span class="n">wrap</span>
</pre></div>
<p>Now, let us say we have a view called get_profile, and say for instance that view can be called only after the above authentication is passed, then we can add the decorator just above the get_profile view definition as shown below.</p>
<div class="codehilite"><pre>@login_required
def update_user_profile():
request_data = request.form
user = User()
response = user.update_user_profile(request_data=request_data, files_data=request.files)
return myresponse(response)
</pre></div>
<h3>Decorator usage for authorization</h3>
<p>Just like how we created a decorator for authentication, we can create one more for authorization as shown below.</p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">wraps</span>
<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">g</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">url_for</span>
<span class="k">def</span> <span class="nf">authorization_required</span><span class="p">():</span>
<span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="nd">@wraps</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">wrap</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span> <span class="n">kwargs</span><span class="p">):</span>
<span class="n">user_id</span> <span class="o">=</span> <span class="n">session</span><span class="p">[</span><span class="s">"user_id"</span><span class="p">]</span>
<span class="n">org</span> <span class="o">=</span> <span class="n">validate_user</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span> <span class="o">//</span><span class="n">this</span> <span class="n">function</span> <span class="n">contains</span> <span class="n">business</span> <span class="n">specific</span> <span class="n">logic</span> <span class="n">to</span> <span class="n">validate</span> <span class="n">user</span>
<span class="k">if</span> <span class="s">"is_active"</span> <span class="ow">in</span> <span class="n">org</span><span class="p">[</span><span class="s">"data"</span><span class="p">]</span> <span class="ow">and</span> <span class="n">org</span><span class="p">[</span><span class="s">"data"</span><span class="p">][</span><span class="s">"is_active"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">({</span>
<span class="s">"message"</span><span class="p">:</span> <span class="n">org</span><span class="p">[</span><span class="s">"message"</span><span class="p">],</span>
<span class="s">"error"</span><span class="p">:</span> <span class="n">org</span><span class="p">[</span><span class="s">"message"</span><span class="p">],</span>
<span class="s">"status_code"</span><span class="p">:</span> <span class="mi">0</span><span class="p">}),</span> <span class="mi">400</span>
<span class="k">return</span> <span class="n">wrap</span>
<span class="k">return</span> <span class="n">decorator</span>
</pre></div>
<p>and now if the request to the view get_profile needs needs to get both authenticated and authorized, then we can add both the decorators just about the view get_profile as shown below.</p>
<div class="codehilite"><pre>@login_required
@organization_required(admin_required=False)
def get_profile(id)
request_data = request.form
user = User()
response = user.update_user_profile(request_data=request_data, files_data=request.files)
return myresponse(response)
</pre></div>Differences between python and java2020-08-03T07:05:20+00:00Balaji P/blog/author/bljd369/http://django.cowhite.com/blog/differences-between-python-and-java/<p>This article is not to discuss the strenghts and weaknesses of both python and java, rather it is to explain and then realize how powerful these two languages are.</p>
<h3>Java:</h3>
<p>If you are a java progarammer, first you need to compile the code that you have written , and this compiled code is nothing but the byte code. This byte code will be executed by the JVM at run time.</p>
<h3>Python:</h3>
<p>It is a scripting language. Each and every line will be interpreted at run time, and even the datatype determination happens at runtime, hence it is a bit slower when compared to java.</p>
<h3>Performance:</h3>
<p>If we compare the peformance between java and python, java will be ahead because type checking in case of java is static, that means the type checking of the variable will happen at compile time. </p>
<p>If there are any symantic errors in your java code, the application server cannot be started,because the type checking happens at compile time itself and this is good actually since the errors are found at initial stage itself.</p>
<p>In case of python, type checking of variables is dynamic in nature, that means the type checking of variables happens during interpretation at run time, so the application server can be started even if you have symantic errors, so that there are chances that the issues will be found only at run time in case of python. Also the processing time will be marginally higher in case of python when compared to java. </p>
<h3>Why I have chosen python over java:</h3>
<p>The above point is not at all a rude shock to the python aspirants, because web page loading is not always about computation, it is something more than that.
The webpages are all about rich user interfaces and in most case, the user interface development is the driving force. Based on the experience I have, at any time, when I think about web development , I always choose python over java and the reason for me is simple, it takes less development time when compared to java.</p>
<p>I know some people say that in case of huge enterprise applications(where the the concept of concurrency come into picture), java is better , and may be they are correct, but if the application that you are developing is not enterprise related, then you can go for python. To make web application development easier with python, we can use frameworks like django, flask.</p>Open edXⓇ - How to create a new Course in Studio2020-07-22T13:44:04+00:00Balaji P/blog/author/bljd369/http://django.cowhite.com/blog/open-edx-how-to-create-a-new-course-in-studio/<p>To create a course, we need to follow the below steps.</p>
<ul>
<li>
<p><strong>Sign in to Studio</strong>: Once we sign into studio, we see a green button in the top right as shown below.
<img alt="alt text" src="https://django.cowhite.com/static/media/uploads/screenshots/createcourse-1-min.png" /></p>
</li>
<li>
<p>We need to click on that button, then we see below screen.</p>
<p><img alt="alt text" src="https://django.cowhite.com/static/media/uploads/screenshots/createcourse-2.png" /></p>
</li>
<li>
<p>Once we fill all the details in the above screen and click on create button, we will get redirected to the below Course outline page.</p>
<p><img alt="alt text" src="https://django.cowhite.com/static/media/uploads/screenshots/createcourse3-min.png" /></p>
<p>As shown in above screen, Course outline page is like a container to the course where it contains one or more
sections and each section contains one or subsections and each subsection contains course units and these course
units contains components and this is our job to develop this course outline.</p>
</li>
</ul>
<p>Now our next steps can be </p>
<ul>
<li>Adding other course team members</li>
<li>setting the course start and end dates</li>
<li>developing the course outline.</li>
</ul>
<h3>Adding course team members to the course:</h3>
<p>In order to give access to your team members to access to Studio, the instructor dashboard in the LMS, and Insights, you need to assign one of the below course team roles to them.
- Staff
- Admin</p>
<p>Below are the prerequisites for adding your team members to Staff and Admin roles.</p>
<ul>
<li>You must be an admin.</li>
<li>the team team that want to add must register a user account and activate the account.</li>
</ul>
<p>Below are the steps to add a team member to your course:</p>
<ul>
<li>
<p>Visit the studio, then you see the list of course as shown below.</p>
<p><img alt="alt text" src="https://django.cowhite.com/static/media/uploads/screenshots/createcourse-4.png" /></p>
</li>
<li>
<p>Then click on the course to which the team members to be added, and then you see the below screen.</p>
<p><img alt="alt text" src="https://django.cowhite.com/static/media/uploads/screenshots/createcourse-5-min.png" /></p>
<p>In the above screen, you can see <strong>settings</strong> dropdown in the top navigation, click on that,then you see Course Team,
now click on course team, then you see the below screen.</p>
<p><img alt="alt text" src="https://django.cowhite.com/static/media/uploads/screenshots/createcourse-6-min.png" /></p>
<p>Now in the above screen, you can see a green button "Add a new team member", click on that, then you see the below
screen.</p>
<p><img alt="alt text" src="https://django.cowhite.com/static/media/uploads/screenshots/createcourse-7.png" /></p>
<p>Once you add the user, the user can start using the studio.
The added user needs to enroll in the course so that he/she can preview the course in LMS.</p>
</li>
</ul>Open edXⓇ - Components of a Course2020-07-20T14:46:44+00:00Balaji P/blog/author/bljd369/http://django.cowhite.com/blog/open-edx-components-of-a-course/<p>For creating the course content, we need to understand below course components.</p>
<ul>
<li>HTML Components</li>
<li>Video Components</li>
<li>Discussion Components</li>
<li>Problem Components</li>
<li>Content Libraries</li>
</ul>
<h3>HTML Components:</h3>
<p>HTML Components are the basic building blocks of your course content. It is like the skeleton of our course. HTML components are used to add and format text, links, images etc. We need to follow the Best Practices for HTML Markup before we start working with HTML components. We can user either Visual Editor or Raw HTML Editor. Visual Editor provides word processing like interface with which we create, edit, and format the content. However, Visual Editor does not provide us full control over the content as it does not support custom formatting or scripts. If we need to include custom formatting or scripts in our content, then we need to go for raw HTML editor.</p>
<h3>Video Components:</h3>
<p>We use video components to add videos to our course in Studio. In video components, we add the name and location of our video, as well as the video transcript. Before we add a video to a course, we need the following items.</p>
<ul>
<li>A place to host, or store, your videos.</li>
<li>A video that meets the recommended specifications.</li>
<li>A transcript for the video.</li>
</ul>
<p>To help make sure all standard browsers can play our video,it is strongly recommended that we use .mp4 format.
Videos should be as short as possible. Because, Learners are more likely to finish watching videos that are no more than 5-10 minutes long.</p>
<h3>Discussion Components:</h3>
<p>A discussion component gives learners a chance to respond to and interact with each other about a specific subject.
Discussion topics that we create by adding discussion components in our course are known as content-specific discussion topics.
When we add a discussion component to a course unit, in the LMS, learners see only the discussion, together with the display name of the discussion component, the category, and the subcategory.
edXⓇ recommends that we add an HTML component before each discussion component to introduce the topic that we want learners to discuss. The discussion component itself does not contain any text and can be easy for learners to overlook.</p>
<h3>Problem Components:</h3>
<p>Using this component, we can add a set of problems to a course. Problems are added to a course outline at the course unit level and these problems can be chosen from Common Problem Type or Advanced list. The common problem types include problems such as multiple choice and text or numeric input. The advanced problem types can be more complex to set up, such as math expression input, open response assessment, or custom JavaScript problems.
Problems can be either graded or ungraded.</p>
<h3>Content Libraries:</h3>
<p>In Studio, we can create a library to build a pool of components for use in randomized assignments in your courses. We can add HTML components, problems, and video components to a library. Open response assessment and discussion components are not supported in libraries.
When you create a library, you are automatically assigned an Admin role in that library.
We can give other Studio users access to your library. These are the levels of access for libraries.</p>
<ul>
<li><strong>User</strong> – Users can view library content and can use library components in their courses, however they cannot edit the contents of a library.</li>
<li><strong>Staff</strong> – Staff can use library components in their courses. In addition, as content co-authors, they have full editing privileges in a library.</li>
<li><strong>Admin</strong> – Admins have full editing privileges for a library. In addition, they can add and remove other team members from library access. There must be at least one user with Admin privileges in a library. </li>
</ul>
<p>We can import and export libraries into the studio. When we import a library, the imported library completely replaces the existing library and its contents. We cannot undo a library import. Before we proceed, it is recommended that we export the current library, so that we have a backup copy of it.</p>Open edXⓇ - How to setup a edXⓇ.org course2020-07-18T06:00:19+00:00Balaji P/blog/author/bljd369/http://django.cowhite.com/blog/open-edx-how-to-setup-a-course/<p>Before setting up a edXⓇ.org course, we need to plan and specify two types of basic information.</p>
<ul>
<li><h5><strong>Course information:</strong></h5>
This info includes course title and number, certificate price, course enrollment tracks, the name of the course administrator of your organization and this info remains constant whether the course runs one time or multiple times.</li>
<li><h5><strong>Course Run information:</strong></h5>
This includes info such as course staff and start date and this info can change every time the course runs.</li>
</ul>
<p>Once the course and course run information is planned, you enter that information into either Publisher or Studio, depending on whether your course will be on edx.org or on Edge.</p>
<p>For courses on edx.org, you enter the course and course run information in Publisher. Publisher is a companion to Studio and is used to create <strong>About pages</strong>.</p>
<p>When you are ready to create a course and course run on edx.org, you add information in the Publisher tool. The information that you enter depends on your goal.</p>
<ul>
<li><strong>Goal1</strong>: If your goal is to enter course content in Studio immediately, you enter a small amount of specific course and course run information in Publisher. <strong>Open edXⓇ</strong> will then create a Studio URL for a course run, and you can add content and modify settings in Studio.</li>
<li><strong>Goal2</strong>: If your goal is to create a course <strong>About page</strong>, you enter all required information in Publisher. Open edXⓇ then creates an About page for your course run and publishes the About page on edx.org.</li>
</ul>
<p>When Publisher creates a Studio URL for the course run, Studio adds the user who created the course run as a course team member. That particular course team member must then add other course team members in Studio.</p>Open edXⓇ - Classification of our team members to different roles2020-07-16T08:16:08+00:00Balaji P/blog/author/bljd369/http://django.cowhite.com/blog/open-edx-classification-of-our-team-members-to-different-roles/<p>Open edXⓇ faciliates us with the below roles to which our team members can be assigned to.</p>
<ul>
<li>Staff</li>
<li>Admin</li>
<li>Beta Testers</li>
<li>Discussion Admins</li>
<li>Discussion Moderators</li>
<li>Discussion Community TAs</li>
</ul>
<h3>Staff & Admin Roles:</h3>
<p>You can assign Staff and Admin roles to your team members when they work in either the LMS or Studio. The people who have these roles can work on your course in Studio(CMS), the LMS, and Insights.</p>
<h3>Beta Testers:</h3>
<p>Beta testers have early access to the course. Beta testers are not members of the course team: they do not have information about “how it is supposed to work”. They use their own computers and Internet connections to view videos, follow links, and complete problems. They interact with the course as students will to find, and make, mistakes.</p>
<h3>Discussion Admins, Discussion Moderators, and Discussion Community TAs:</h3>
<p>To moderate course discussions, team members must have one of these discussion roles assigned to them in addition to the Staff or Admin role.</p>
<h3>Discussion admins:</h3>
<p>This role have priviliges to work on discussions as moderators. Whenever a discussion admin responds or comments to a discussion and their posts, he will be identified as staff by the learners. This role can be reserved for assignment to course team members who have the Admin role only: the discussion admins can then both moderate discussions and give other users these discussion management roles whenever necessary.</p>
<h3>Discussion community TAs:</h3>
<p>This role have the same privileges as Discussion Admins.However, posts made by community TAs are marked as “By: Community TA” in the list of posts on the Discussion page. Responses and comments made by community TAs have a colored “Community TA” identifier. This role is often given to students.</p>
<h3>Discussion moderators:</h3>
<p>Discussion moderators can edit and delete messages at any level, review messages flagged for misuse, close and reopen posts, pin posts, and endorse responses. Posts made by moderators are marked as “By: Staff” in the list of posts. Responses and comments made by moderators have a colored “Staff” identifier. This role is often given to course team members who already have the Staff role.</p>Open edXⓇ - What is CMS?2020-07-15T10:08:23+00:00Balaji P/blog/author/bljd369/http://django.cowhite.com/blog/open-edx-what-is-cms/<p>CMS: It is a powerful tool which is useful for the content providers and course teams. This is also called studio, because all the stuff that we show to the learners is created and edited here. Below are some of the things that the content providers and course teams do using CMS.</p>
<h3>Developing Course Building Blocks:</h3>
<p>Studio enables us to create building blocks like as mentioned below.</p>
<ul>
<li>The course outline is the container for all of your course content. The outline contains one or more sections.</li>
<li>The course section is at the top level of your course and typically represent a time period. A section contains one or more subsections.</li>
<li>The course subsection is part of a section, and usually represent a topic or other organizing principle. A subsection contains one or more units.</li>
<li>course unit is a lesson in a subsection that learners view as single pages. A unit contains one or more components.</li>
<li>course component is an object lesson in a subsection that learners view as single pages. A unit contains one or more components.</li>
</ul>
<h3>Adding Files like Images to a Course:</h3>
<p>Content providers manage mostly files for the course, including image files, on the Files & Uploads page available.</p>
<h3>Creating and Adding Video Content:</h3>
<p>For edx.org courses, you upload your videos to the Video Uploads page available in studio. The edXⓇ video process then creates multiple formats and sources for your videos.</p>
<h3>Adding Problems, Exercises, and Tools:</h3>
<p>You can add a wide variety of different types of problems, exercises, and tools to the course outline. </p>
<h3>Developing Course Components:</h3>
<p>A component is the part of a unit that contains your actual course content. A unit can contain one or more components.
By default, Studio includes four basic types of components for you to add to your course.</p>
<ul>
<li>Discussion components provide discussion spaces in the body of your course. Learners can explore ideas about a lesson with their peers in a discussion space.</li>
<li>HTML components allow you to add text, images, and some types of learning tools to your course. Content in HTML components is formatted as HTML.</li>
<li>Problem components enable you to add many different types of exercises and problems to your course, from simple multiple choice problems to complex circuit schematic exercises.</li>
<li>Video components contain the videos that you want to include in your course.</li>
</ul>Reading QR Code from Image using python2019-01-02T08:29:19+00:00bhaskar/blog/author/bhaskar/http://django.cowhite.com/blog/reading-qr-code-from-image-using-python/<p>In this post, I will show you how to read QR Code from image using python</p>
<p>We will be using the open source app "qrtools" to read image.</p>
<h3>qrtools installation:</h3>
<p>Install zbar systemwide</p>
<div class="codehilite"><pre>sudo apt-get install libzbar-dev
</pre></div>
<p>Then create virtualenv and then install requirements</p>
<div class="codehilite"><pre>pip install pypng zbar pillow qrtools
</pre></div>
<p>Where pypng, zbar and pillow are the dependencies required by qrtools.</p>
<p>Code to read QR Code from Image:</p>
<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">qrtools</span>
<span class="n">qr</span> <span class="o">=</span> <span class="n">qrtools</span><span class="o">.</span><span class="n">QR</span><span class="p">()</span>
<span class="n">qr</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">"QR_Code.png"</span><span class="p">)</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">qr</span><span class="o">.</span><span class="n">data</span>
<span class="k">print</span><span class="p">(</span><span class="s">"The decoded QR code is: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="n">s</span><span class="p">)</span>
</pre></div>Open edXⓇ - Open source MOOC platform2018-06-17T03:15:17+00:00bhaskar/blog/author/bhaskar/http://django.cowhite.com/blog/open-edx-open-source-mooc-platform/<p>Open edXⓇ is an open source course management platform that allows instructors/teachers to add course content(videos, text content, images, forum discussion, assessment etc) and then the students can enroll to the courses(free or paid) and view the courses.</p>
<p>Open edXⓇ has the following main components(in general sense):</p>
<ul>
<li>LMS - Where students can enroll and view the courses</li>
<li>CMS - Where instructors can add course content and manage them </li>
<li>Ecommerce - Open edXⓇ uses django-oscar for managing the ecommerce section. Cybersource and paypal are available by default. But you can integrate any other payment gateway. </li>
<li>XBlocks - Its Edx'sⓇ component architecture. It allows people to contribute various components and developers can integrate some of the XBlocks for use in their application as per their requirement. Here are the list of XBlocks - https://openedx.atlassian.net/wiki/spaces/COMM/pages/43385346/XBlocks+Directory</li>
</ul>
<h3>Releases:</h3>
<p>Open edXⓇ has multiple releases as of now. These are the releases:</p>
<table class='table table-bordered'>
<thead>
<tr>
<td>Release Name</td>
<td>Release Date</td>
<td>Git Tag</td>
</tr>
</thead>
<tbody>
<tr>
<td>GInkgo.2 (Latest release)</td>
<td>2017-12-18</td>
<td>open-release/ginkgo.2</td>
</tr>
<tr>
<td>Ginkgo.1</td>
<td>2017-08-14</td>
<td>open-release/ginkgo.1</td>
</tr>
<tr>
<td>Ficus.4</td>
<td>2017-08-10</td>
<td>open-release/ficus.4</td>
</tr>
<tr>
<td>Ficus.3</td>
<td>2017-04-21</td>
<td>open-release/ficus.3
</td>
</tr>
<tr>
<td>Ficus.2</td>
<td>2017-03-29</td>
<td>open-release/ficus.2</td>
</tr>
<tr>
<td>Ficus.1</td>
<td>2017-02-23</td>
<td>open-release/ficus.1</td>
</tr>
<tr>
<td>Eucalyptus.3</td>
<td>2017-01-10</td>
<td>open-release/eucalyptus.3</td>
</tr>
<tr>
<td>Eucalyptus.2</td>
<td>2016-09-02</td>
<td>open-release/eucalyptus.2</td>
</tr>
</tbody>
</table>
<p>And other older releases: Eucalyptus.1, Dogwood.3, Dogwood.2, Dogwood.1, Dogwood, Cypress, Birch.2, Birch.1, Birch, Aspen.</p>
<p>In the next blog post, we will explore clearly on the open edXⓇ devstack installation and open edXⓇ native installation.</p>
<p>Are you looking for Open edXⓇ development/installation/customization ? We can do it for you. Please email us to hello@cowhite.com.</p>
<p>“edX, Open edX, and MicroMasters are registered trademarks of edX Inc. MicroBachelors is a trademark of edX Inc. All Rights Reserved.”</p>Exporting and importing data in Django using pg_dump in postgresql, mysqldump in mysql, dumpdata and loaddata commands in Django2018-05-28T14:35:06+00:00bhaskar/blog/author/bhaskar/http://django.cowhite.com/blog/exporting-and-importing-data-in-django-using-pg_dump-in-postgresql-mysqldump-in-mysql-dumpdata-and-loaddata-commands-in-django/<p>In this tutorial, I will explain how to export and import data in a Django project.</p>
<p>Data export/import of a Django project simply means the export/import of the data present in the database that the Django project uses.</p>
<p>Lets talk about the export/import of two popular databases and then directly from Django:</p>
<div class="codehilite"><pre>1. PostgresSql
2. MySql
</pre></div>
<h3>Exporting and importing data from a PostgresSql database:</h3>
<h3>Exporting:</h3>
<p>Syntax:</p>
<div class="codehilite"><pre><span class="nx">pg_dump</span> <span class="na">-U</span> <span class="o"><</span><span class="nx">db_username</span><span class="o">></span> <span class="o"><</span><span class="nx">db_name</span><span class="o">></span> <span class="na">-h</span> <span class="o"><</span><span class="nx">host</span><span class="o">></span> <span class="na">-t</span> <span class="o"><</span><span class="nb">table_name</span><span class="o">></span> <span class="o">></span> <span class="nx">exported_data.sql</span>
</pre></div>
<p>Example for exporting with database user 'myuser', database name 'db_name', host 'localhost':</p>
<div class="codehilite"><pre>pg_dump -U myuser db_name -h localhost > exported_data.sql
</pre></div>
<p>If the host is a remote ip (1.2.3.4 for example), then</p>
<div class="codehilite"><pre>pg_dump -U myuser db_name -h 1.2.3.4 > exported_data.sql
</pre></div>
<p>Exporting a single table can be done using "-t table_name" as follows:</p>
<div class="codehilite"><pre>pg_dump -U myuser db_name -h 1.2.3.4 -t table_name > exported_data.sql
</pre></div>
<h3>Importing:</h3>
<p>Syntax:</p>
<div class="codehilite"><pre><span class="nx">psql</span> <span class="na">-U</span> <span class="o"><</span><span class="nx">db_username</span><span class="o">></span> <span class="o"><</span><span class="nx">db_name</span><span class="o">></span> <span class="na">-h</span> <span class="o"><</span><span class="nx">host</span><span class="o">></span> <span class="o"><</span> <span class="nx">exported_data.sql</span>
</pre></div>
<p>Example for importing with database user 'myuser', database name 'db_name', host 'localhost':</p>
<div class="codehilite"><pre>pg_dump -U myuser db_name -h localhost < exported_data.sql
</pre></div>
<p>If the host is a remote ip (1.2.3.4 for example), then</p>
<div class="codehilite"><pre>pg_dump -U myuser db_name -h 1.2.3.4 < exported_data.sql
</pre></div>
<h3>Exporting/importing data from a MySql database:</h3>
<h3>Exporting:</h3>
<p>Syntax:</p>
<div class="codehilite"><pre><span class="nx">mysqldump</span> <span class="na">-u</span> <span class="o"><</span><span class="nx">db_username</span><span class="o">></span> <span class="o"><</span><span class="nx">db_name</span><span class="o">></span> <span class="o"><</span><span class="nb">table_name</span><span class="o">></span> <span class="o">--</span><span class="nx">password</span> <span class="o">></span> <span class="nx">exported_mysql_data.sql</span>
</pre></div>
<p>Example for exporting with database user 'myuser', database name 'db_name', host 'localhost' or 127.0.0.1 or any remote host:</p>
<div class="codehilite"><pre>mysqldump -u myuser db_name -h localhost --password > exported_mysql_data.sql
</pre></div>
<p>If the host is a remote ip (1.2.3.4 for example), then</p>
<div class="codehilite"><pre>mysqldump -u myuser db_name -h 1.2.3.4 --password > exported_mysql_data.sql
</pre></div>
<p>Exporting a single table can be done using as follows:</p>
<div class="codehilite"><pre>mysqldump -u myuser db_name table_name -h 1.2.3.4 > exported_mysql_data.sql
</pre></div>
<h3>Importing:</h3>
<p>Syntax:</p>
<div class="codehilite"><pre><span class="nx">mysql</span> <span class="na">-u</span> <span class="o"><</span><span class="nx">db_username</span><span class="o">></span> <span class="o"><</span><span class="nx">db_name</span><span class="o">></span> <span class="na">-h</span> <span class="o"><</span><span class="nx">host</span><span class="o">></span> <span class="o">--</span><span class="nx">password</span> <span class="o"><</span> <span class="nx">exported_mysql_data.sql</span>
</pre></div>
<p>Example for importing with database user 'myuser', database name 'db_name', host 'localhost':</p>
<div class="codehilite"><pre>mysql -u myuser db_name -h localhost --password < exported_mysql_data.sql
</pre></div>
<p>If the host is a remote ip (1.2.3.4 for example), then</p>
<div class="codehilite"><pre>mysql -u myuser db_name -h 1.2.3.4 --password < exported_mysql_data.sql
</pre></div>
<h3>Exporting and Importing data from a Django project</h3>
<p>Django provides two management commands for this purpose</p>
<div class="codehilite"><pre>1. dumpdata
2. loaddata
</pre></div>
<h3>Management command: Dumpdata</h3>
<p>The management command 'dumpdata' dumps the data in the JSON format. This JSON data can be exported to any Django project irrespective of the database behind it (in most cases). </p>
<div class="codehilite"><pre>python manage.py dumpdata > dumped_data.json
</pre></div>
<p>If you want the exported file to have a readable JSON, then you can use "--indent". It will export data in JSON format with the specified indentation.</p>
<div class="codehilite"><pre>python manage.py dumpdata --indent=4 > dumped_data.json
</pre></div>
<h3>Management command: Loaddata</h3>
<p>The management command 'loaddata' loads the data that we just exported. Note that the data that we export from postgresql, mysql databases using pg_dump, mysqldump cant be loaded here and vice versa. </p>
<p>Here is the syntax:</p>
<div class="codehilite"><pre>python manage.py loaddata < dumped_data.json
</pre></div>Opensourced Django invitation system with roles and permissions2018-05-17T10:57:59+00:00bhaskar/blog/author/bhaskar/http://django.cowhite.com/blog/opensourced-django-invitation-system-with-roles-and-permissions/<p>In this blog post, I will explain about the opensourced invitation/member system with roles and permissions that we have developed recently.</p>
<p>Github link:</p>
<div class="codehilite"><pre>https://github.com/cowhite/django-members-roles
</pre></div>
<p>Installation:</p>
<div class="codehilite"><pre>pip install django-members-roles
</pre></div>
<p>More details on installation and setup at <a href="https://django-members-roles.readthedocs.io">https://django-members-roles.readthedocs.io</a>. </p>
<h3>Features</h3>
<ul>
<li>Invitation system where you can invite people to be the members of your group(any content type like organization for example)</li>
<li>Add roles to the members of the group</li>
<li>Define permissions for the pages all over the project(or only some) and decide the access to the project pages by assigning necessary roles.</li>
</ul>Using GeoDjango in your Django project2018-05-16T14:41:47+00:00sankar/blog/author/sankar/http://django.cowhite.com/blog/using-geodjango-in-your-django-project/<p>In this tutorial, I will explain to you how to use GeoDjango in Django project.
Let us assume you have UserProfile in your Django project.</p>
<div class="codehilite"><pre><span class="k">class</span> <span class="n">UserProfile</span>(<span class="n">models</span>.<span class="n">Model</span>):
<span class="n">user</span> = <span class="n">models</span>.<span class="n">ForeignKey</span>(<span class="n">User</span>)
</pre></div>
<p>for using GeoDjango in our project we need PostgreSQL DB. Lets create our DB in PostgreSQL and extend to PostGIS.</p>
<div class="codehilite"><pre>> sudo -u postgres psql
postgres=# create user django_geo with password 'django_geo';
postgres=# create database djangogeo owner django_geo;
postgres=# ALTER USER django_geo SUPERUSER; //giving sudo permission to user.
postgres=# \c djangogeo //switch to djangogeo DB
djangogeo=# CREATE EXTENSION postgis;
</pre></div>
<p>We are ready with PostgreSQL DATABASE. Let's add our DB details in our Django settings.</p>
<div class="codehilite"><pre>DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'djangogeo',
'USER': 'django_geo',
'PASSWORD': "django_geo",
'HOST' : 'localhost',
'PORT' : '',
},
}
</pre></div>
<p>Add 'django.contrib.gis' in our INSTALLED_APPS</p>
<div class="codehilite"><pre>INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.gis',
#internal apps
'my_app',
</pre></div>
<p>]</p>
<p>We are done with GeoDjango setup in our project. Do migrations for creating DB tables for our new database.</p>
<div class="codehilite"><pre>> ./manage.py migrate
</pre></div>
<p>Let's start editing our UserProfile model where we want to save user geolocation details.</p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">django.contrib.gis.db</span> <span class="kn">import</span> <span class="n">models</span>
<span class="k">class</span> <span class="nc">UserProfile</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
<span class="n">user</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">User</span><span class="p">)</span>
<span class="n">geo_location</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">PointField</span><span class="p">(</span><span class="n">srid</span><span class="o">=</span><span class="mi">4326</span><span class="p">,</span> <span class="n">null</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span><span class="n">blank</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">geo_objects</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">GeoManager</span><span class="p">()</span>
</pre></div>
<h3>Adding location details to UserProfile:</h3>
<p>Let's see how to add location details in UserProfile using Django shell</p>
<div class="codehilite"><pre><span class="o">></span> <span class="n">python</span> <span class="n">manage</span><span class="o">.</span><span class="n">py</span> <span class="n">shell</span>
<span class="o">></span> <span class="kn">from</span> <span class="nn">my_app.models</span> <span class="kn">import</span> <span class="n">UserProfile</span>
<span class="o">></span> <span class="kn">from</span> <span class="nn">django.contrib.gis.geos</span> <span class="kn">import</span> <span class="n">Point</span> <span class="c">#GeoDjango takes lat and lng values in Point object.</span>
<span class="o">></span> <span class="n">lat</span> <span class="o">=</span> <span class="mf">17.5013714</span>
<span class="o">></span> <span class="n">lng</span> <span class="o">=</span> <span class="mf">78.3878926</span>
<span class="o">></span> <span class="n">location_point</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">lng</span><span class="p">,</span> <span class="n">lat</span><span class="p">)</span> <span class="c">#creating point object.</span>
<span class="o">></span> <span class="n">user_profile</span> <span class="o">=</span> <span class="n">UserProfile</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">first</span><span class="p">()</span> <span class="c">#Assume we are adding geo location for first userprofile object.</span>
<span class="o">></span> <span class="n">user_profile</span><span class="o">.</span><span class="n">geo_location</span> <span class="o">=</span> <span class="n">location_point</span>
<span class="o">></span> <span class="n">user_profile</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre></div>
<h3>GeoDjango distance queries</h3>
<p>Query users within a 10km/100meter's/10mile's distance from your location</p>
<div class="codehilite"><pre><span class="o">></span> <span class="kn">from</span> <span class="nn">my_app.models</span> <span class="kn">import</span> <span class="n">UserProfile</span>
<span class="o">></span> <span class="kn">from</span> <span class="nn">django.contrib.gis.measure</span> <span class="kn">import</span> <span class="n">D</span>
<span class="o">></span> <span class="n">user_profile</span> <span class="o">=</span> <span class="n">UserProfile</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">first</span><span class="p">()</span> <span class="c">#Assume first object is required user profile</span>
<span class="c"># Query for 10km</span>
<span class="o">></span> <span class="n">UserProfile</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">geo_location__distance_lte</span><span class="o">=</span><span class="p">(</span><span class="n">user_profile</span><span class="o">.</span><span class="n">geo_location</span><span class="p">,</span> <span class="n">D</span><span class="p">(</span><span class="n">km</span><span class="o">=</span><span class="mi">10</span><span class="p">)))</span>
<span class="c"># Query for 100meter's</span>
<span class="o">></span> <span class="n">UserProfile</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">geo_location__distance_lte</span><span class="o">=</span><span class="p">(</span><span class="n">user_profile</span><span class="o">.</span><span class="n">geo_location</span><span class="p">,</span> <span class="n">D</span><span class="p">(</span><span class="n">m</span><span class="o">=</span><span class="mi">100</span><span class="p">)))</span>
<span class="c"># Query for 10mile's</span>
<span class="o">></span> <span class="n">UserProfile</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">geo_location__distance_lte</span><span class="o">=</span><span class="p">(</span><span class="n">user_profile</span><span class="o">.</span><span class="n">geo_location</span><span class="p">,</span> <span class="n">D</span><span class="p">(</span><span class="n">mi</span><span class="o">=</span><span class="mi">10</span><span class="p">)))</span>
</pre></div>
<p>Query users between 5 to 10 km distance from your location</p>
<div class="codehilite"><pre><span class="o">></span> <span class="kn">from</span> <span class="nn">my_app.models</span> <span class="kn">import</span> <span class="n">UserProfile</span>
<span class="o">></span> <span class="kn">from</span> <span class="nn">django.contrib.gis.measure</span> <span class="kn">import</span> <span class="n">D</span>
<span class="o">></span> <span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
<span class="o">></span> <span class="n">user_profile</span> <span class="o">=</span> <span class="n">UserProfile</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="o">></span> <span class="n">UserProfile</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">Q</span><span class="p">(</span><span class="n">geo_location__distance_gte</span><span class="o">=</span><span class="p">(</span><span class="n">user_profile</span><span class="o">.</span><span class="n">geo_location</span><span class="p">,</span> <span class="n">D</span><span class="p">(</span><span class="n">km</span><span class="o">=</span><span class="mi">5</span><span class="p">)))</span>
<span class="o">&</span> <span class="n">Q</span><span class="p">(</span><span class="n">geo_location__distance_gte</span><span class="o">=</span><span class="p">(</span><span class="n">user_profile</span><span class="o">.</span><span class="n">geo_location</span><span class="p">,</span> <span class="n">D</span><span class="p">(</span><span class="n">km</span><span class="o">=</span><span class="mi">5</span><span class="p">))))</span>
</pre></div>Building single page applications easily with cowhite.js2018-05-10T14:08:10+00:00bhaskar/blog/author/bhaskar/http://django.cowhite.com/blog/building-single-page-applications-easily-with-cowhitejs/<p>In this tutorial, I will explain you how to build single page applications easily using cowhite.js.</p>
<h3>Links:</h3>
<p>Opensource code at github - <a href="https://github.com/cowhite/Cowhite.js" target="_blank">https://github.com/cowhite/Cowhite.js</a>.</p>
<p>Documentation at <a href="https://cowhitejs.readthedocs.io" target="_blank">https://cowhitejs.readthedocs.io</a>.</p>
<p>Download link of cowhite.js - <a href="https://github.com/cowhite/Cowhite.js/blob/master/cowhite.js" target="_blank">https://github.com/cowhite/Cowhite.js/blob/master/cowhite.js</a>. (Dont embed this link in website, instead download and use)</p>
<h3>What is Cowhite.js ?</h3>
<p>Cowhite.js is a small jquery library that we developed to make our work easier. We have built the following features in Cowhite.js:</p>
<div class="codehilite"><pre>1. Build single page applications(spa)
2. Submit forms
3. Button actions
</pre></div>
<h3>1. Build single page applications(spa):</h3>
<p>Lets say we are building a single page application where we have the urls which when opened, load the main content without re-loading staticfiles etc. Let these pages be page1, page2 and page3. Then the urls will be of the format:</p>
<div class="codehilite"><pre>example.com#page1
example.com#page2
example.com#page3
</pre></div>
<p>To make this work, we need to add below html:</p>
<div class="codehilite"><pre><span class="nt"><div</span> <span class="na">id=</span><span class="s">'page1-section'</span> <span class="na">class=</span><span class="s">'each-section hide'</span> <span class="nt">></span>
<span class="nt"><p></span>Page 1 content here<span class="nt"></p></span>
<span class="nt"></div></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">'page2-section'</span> <span class="na">class=</span><span class="s">'each-section hide'</span> <span class="nt">></span>
<span class="nt"><p></span>Page 2 content here<span class="nt"></p></span>
<span class="nt"></div></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">'page3-section'</span> <span class="na">class=</span><span class="s">'each-section hide'</span> <span class="nt">></span>
<span class="nt"><p></span>Page 3 content here<span class="nt"></p></span>
<span class="nt"></div></span>
</pre></div>
<p>Then, if you open the url http://yourdomain.com#page1, then the content inside page1-section will be visible. </p>
<h3>2. Load and insert data automatically from remote url:</h3>
<p>In the previous example, we are simply switching between pages/sections and then the static content present inside each page/section is displayed. Here, we will show how to load data from remote url automatically, that is, without writing code for loading content.</p>
<div class="codehilite"><pre><span class="nt"><div</span> <span class="na">id=</span><span class="s">'page1-section'</span> <span class="na">class=</span><span class="s">'each-section hide'</span> <span class="na">data-url=</span><span class="s">"https://cowhitejs.cowhite.com/assets/data/items_list.html"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">'page1-content'</span><span class="nt">></div></span>
<span class="nt"></div></span>
</pre></div>
<p>Whenever a page/section is loaded, it will look for data attribute "url", that is, data-url. And then will make an ajax call to that url and inserts the result into the html element with id "page1-content". Here page1 is the page name/hash name with section id as "page1-section". This is useful when you simply want to load some remote html when loading a page.</p>
<h3>3. Load data from remote url automatically but render that content to the dom manually:</h3>
<p>This is useful when the response is JSON/XML but not html. You need to write a callback and then add the data attribute data-callback to the section like below:</p>
<div class="codehilite"><pre> <span class="nt"><div</span> <span class="na">id=</span><span class="s">'page1-section'</span> <span class="na">class=</span><span class="s">'each-section hide'</span> <span class="na">data-callback=</span><span class="s">"loadPage1Callback"</span> <span class="na">data-url=</span><span class="s">"https://marketing.cowhite.com/api/v1/items/"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">'page1-content'</span><span class="nt">></div></span>
<span class="nt"></div></span>
</pre></div>
<p>Code for callback in javascript:</p>
<div class="codehilite"><pre>function loadPage1Callback(res)<span class="err">{</span>
var html = "", <span class="p">$</span><span class="nv">page1ItemHtml</span> = <span class="p">$(</span><span class="s2">"#page1-template"</span><span class="p">)</span>, page1ItemHtml;
for(var i=0; i<span class="nt"><res.results.length</span><span class="err">;</span> <span class="err">i++){</span>
<span class="na">page1ItemHtml =</span> <span class="p">$</span><span class="nv">page1ItemHtml</span><span class="p">.</span><span class="nv">html</span><span class="p">().</span><span class="nv">replace</span><span class="p">(</span><span class="err">/ITEM_ID/g</span><span class="p">,</span> <span class="err">res.results</span><span class="p">[</span><span class="err">i</span><span class="p">]</span><span class="err">.id</span><span class="p">).</span><span class="nv">replace</span><span class="p">(</span>
<span class="err">/ITEM/g</span><span class="p">,</span> <span class="err">res.results</span><span class="p">[</span><span class="err">i</span><span class="p">]</span><span class="err">.name</span><span class="p">)</span><span class="s">;</span>
<span class="err">html</span> <span class="err">+=</span> <span class="err">page1ItemHtml;</span>
<span class="err">}</span>
<span class="err">if(!res.results.length){</span>
<span class="err">html</span> <span class="err">+=</span> <span class="err">"<div</span><span class="nt">></span>No items yet.<span class="nt"></div></span>"
}
<span class="p">$(</span><span class="s2">"#page1-content"</span><span class="p">).</span><span class="nv">html</span><span class="p">(</span><span class="err">html</span><span class="p">)</span>;
}
</pre></div>
<h3>4. Load content/data manually:</h3>
<p>There may be situation when you want to do things on your own when a particular page is loaded. Then we can use the events fired when a page is loaded.</p>
<p>If the page with hash "page1" is loaded, then the event fired is "page1-opened". </p>
<p>We can write html like this:</p>
<div class="codehilite"><pre> <span class="nt"><div</span> <span class="na">id=</span><span class="s">'page1-section'</span> <span class="na">class=</span><span class="s">'each-section hide'</span> <span class="nt">></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">'page1-content'</span><span class="nt">></div></span>
<span class="nt"></div></span>
</pre></div>
<p>Write code in javascript that catches the event "page1-opened" that cowhite.js fired</p>
<div class="codehilite"><pre><span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s2">"page1-opened"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(){</span>
<span class="c1">// write code here </span>
<span class="c1">// For example, you can make ajax call to some url and insert that response to the dom(any element as you wish)</span>
<span class="p">});</span>
</pre></div>
<p>You can look more of the documentation at <a href="https://cowhitejs.readthedocs.io">https://cowhitejs.readthedocs.io</a>. </p>Database API and Django Admin2017-08-17T04:00:00+00:00srinath/blog/author/srinath/http://django.cowhite.com/blog/database-api-and-django-admin/<h3>Database API</h3>
<p>
In <a href="https://django.cowhite.com/blog/models-migrations-and-django-admin/">last tutorial</a> we left off by creating and migrating models. This means that we have everything ready and the only thing we need to do is add data into the database. For doing so Django has a Database API which allows us to access and manipulate the database using Python code only. Let's play with this API and learn them on the way. We can use the Python shell to do so. Type the following to open the Python shell
</p>
<p><br/>
<p id="shell">
<pre>
<code>
python manage.py shell
</code>
</pre>
</p><br/>
<p>
Once in the shell, let's <strong>explore the Database API</strong>.
</p><br/>
<p></p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">polls.models</span> <span class="kn">import</span> <span class="n">Question</span><span class="p">,</span> <span class="n">Choice</span> <span class="c"># Import the model classes we just wrote.</span>
<span class="c"># currently the database is empty.</span>
<span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="c"># Output: </span>
<span class="c"># <Queryset []></span>
<span class="n">Choice</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="c"># Output:</span>
<span class="c"># <Queryset []></span>
<span class="c"># Let's create a new Question first</span>
<span class="c"># If you remember the Question model has a pub_date field, which stores a datetime</span>
<span class="c"># Although Python has datetime.datetime.now(),</span>
<span class="c"># we will use the Django's implementation of the same</span>
<span class="c"># which uses the timezone setting to create a datetime</span>
<span class="c"># with timezone info included.</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">timezone</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">Question</span><span class="p">(</span><span class="n">question_text</span><span class="o">=</span><span class="s">"What would you say, Dear Sir, is up?"</span><span class="p">,</span> <span class="n">pub_date</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">now</span><span class="p">())</span>
<span class="c"># The above statement only creates a Python Model Object.</span>
<span class="c"># To persist it in the database we do the following</span>
<span class="n">q</span><span class="o">.</span><span class="n">save</span><span class="p">();</span>
<span class="c"># Above 2 statements can be combined using the objects.create() method as follows</span>
<span class="c"># It creates the Python model and saves it in Database in a single statement</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">question_text</span><span class="o">=</span><span class="s">"What would you say, Dear Sir, is up?"</span><span class="p">,</span> <span class="n">pub_date</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">now</span><span class="p">())</span>
<span class="c"># Access the model fields as Python attributes</span>
<span class="n">q</span><span class="o">.</span><span class="n">id</span>
<span class="c"># Output:</span>
<span class="c"># 1</span>
<span class="c"># Note: In some databases the above value may be 1L instead of just being 1.</span>
<span class="c"># It is completely normal,</span>
<span class="c"># Python read them as Long integers rather than regular integers.</span>
<span class="n">q</span><span class="o">.</span><span class="n">question_text</span>
<span class="c"># Output:</span>
<span class="c"># "What's up?"</span>
<span class="n">q</span><span class="o">.</span><span class="n">pub_date</span>
<span class="c"># Output:</span>
<span class="c"># datetime.datetime(2017, 6, 01, 13, 0, 0, 775217, tzinfo=<UTC>)</span>
<span class="c"># Changing the value is as simple as changing the attributes and then calling save().</span>
<span class="n">q</span><span class="o">.</span><span class="n">question_text</span> <span class="o">=</span> <span class="s">"What's up"</span>
<span class="n">q</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="c"># To list all the questions in database, we use objects.all().</span>
<span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="c"># Output:</span>
<span class="c"># <QuerySet [<Question: Question object>]></span>
</pre></div>
<p></p><br/>
<p>
<strong><Question: Question object></strong> is a completely useless annotation for an object. We can change this by mentioning the string representation for any Model object. We do so by adding a <code>__str__()</code> method in the model declaration.
</p><br/>
<p></p>
<div class="codehilite"><pre><span class="c"># Python Code</span>
<span class="c"># polls/models.py</span>
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>
<span class="kn">from</span> <span class="nn">django.utils.encoding</span> <span class="kn">import</span> <span class="n">python_2_unicode_compatible</span>
<span class="nd">@python_2_unicode_compatible</span> <span class="c"># only if you need to support Python 2</span>
<span class="k">class</span> <span class="nc">Question</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
<span class="c"># ...</span>
<span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">question_text</span>
<span class="nd">@python_2_unicode_compatible</span> <span class="c"># only if you need to support Python 2</span>
<span class="k">class</span> <span class="nc">Choice</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
<span class="c"># ...</span>
<span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">choice_text</span>
</pre></div>
<p></p><br/>
<p>
Now the Question object will be displayed as follows:
</p><br/>
<p></p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">polls.models</span> <span class="kn">import</span> <span class="n">Question</span><span class="p">,</span> <span class="n">Choice</span>
<span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="c"># Output:</span>
<span class="c"># <QuerySet [<Question: What's up?>]></span>
</pre></div>
<p></p><br/>
<p>
It’s important to add <code>__str__()</code> methods to your models, not only for your own convenience when dealing with the interactive prompt, but also because objects’ representations are used throughout Django’s automatically-generated admin.
</p><br/>
<p>
We could also add <strong>custom methods</strong> to the model and make them rich with convenience methods.
</p><br/>
<p></p>
<div class="codehilite"><pre><span class="c"># Python Code</span>
<span class="c"># polls/models.py</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">timezone</span>
<span class="k">class</span> <span class="nc">Question</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
<span class="c"># ...</span>
<span class="k">def</span> <span class="nf">was_published_recently</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pub_date</span> <span class="o">>=</span> <span class="n">timezone</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
<p></p><br/>
<p>
Now we can get a computed information using this method for a Question model object. Note the addition of <code>import datetime</code> and <code>from django.utils import timezone</code>, to reference Python’s standard <code>datetime</code> module and Django’s time-zone-related utilities in <code>django.utils.timezone</code>, respectively.
</p><br/>
<p>
Save these changes and <a target="_blank" href="https://django.cowhite.com/blog/database-api-and-django-admin#shell">start a new Python interactive shell</a> again.
</p><br/>
<p></p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">polls.models</span> <span class="kn">import</span> <span class="n">Question</span><span class="p">,</span> <span class="n">Choice</span>
<span class="c"># Django provides a rich database lookup API that's entirely driven by</span>
<span class="c"># keyword arguments.</span>
<span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># Output:</span>
<span class="c"># <Question: What's up?></span>
<span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># Output:</span>
<span class="c"># <QuerySet [<Question: What's up?>]></span>
<span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">question_text__startswith</span><span class="o">=</span><span class="s">'What'</span><span class="p">)</span>
<span class="c"># Output:</span>
<span class="c"># <QuerySet [<Question: What's up?>]></span>
<span class="c"># Get the question that was published this year.</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">timezone</span>
<span class="n">current_year</span> <span class="o">=</span> <span class="n">timezone</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">year</span>
<span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pub_date__year</span><span class="o">=</span><span class="n">current_year</span><span class="p">)</span>
<span class="c"># Output:</span>
<span class="c"># <Question: What's up?></span>
<span class="c"># Request an ID that doesn't exist, this will raise an exception.</span>
<span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="c"># Output:</span>
<span class="c"># Traceback (most recent call last):</span>
<span class="c"># ...</span>
<span class="c"># DoesNotExist: Question matching query does not exist.</span>
<span class="c"># Lookup by a primary key is the most common case, so Django provides a</span>
<span class="c"># shortcut for primary-key exact lookups.</span>
<span class="c"># The following is identical to Question.objects.get(id=1).</span>
<span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># Output:</span>
<span class="c"># <Question: What's up?></span>
<span class="c"># Make sure our custom method worked.</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">q</span><span class="o">.</span><span class="n">was_published_recently</span><span class="p">()</span>
<span class="c"># Output:</span>
<span class="c"># True</span>
<span class="c"># Give the Question a couple of Choices. The create call constructs a new</span>
<span class="c"># Choice object, does the INSERT statement, adds the choice to the set</span>
<span class="c"># of available choices and returns the new Choice object. Django creates</span>
<span class="c"># a set to hold the "other side" of a ForeignKey relation</span>
<span class="c"># (e.g. a question's choice) which can be accessed via the API.</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">Question</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c"># Display any choices from the related object set -- none so far.</span>
<span class="n">q</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="c"># Output:</span>
<span class="c"># <QuerySet []></span>
<span class="c"># Create three choices.</span>
<span class="n">q</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">choice_text</span><span class="o">=</span><span class="s">'Not much'</span><span class="p">,</span> <span class="n">votes</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="c"># Output:</span>
<span class="c"># <Choice: Not much></span>
<span class="n">q</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">choice_text</span><span class="o">=</span><span class="s">'The sky'</span><span class="p">,</span> <span class="n">votes</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="c"># Output:</span>
<span class="c"># <Choice: The sky></span>
<span class="n">c</span> <span class="o">=</span> <span class="n">q</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">choice_text</span><span class="o">=</span><span class="s">'Just hacking again'</span><span class="p">,</span> <span class="n">votes</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="c"># Choice objects have API access to their related Question objects.</span>
<span class="n">c</span><span class="o">.</span><span class="n">question</span>
<span class="c"># Output:</span>
<span class="c"># <Question: What's up?></span>
<span class="c"># And vice versa: Question objects get access to Choice objects.</span>
<span class="n">q</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="c"># Output:</span>
<span class="c"># <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]></span>
<span class="n">q</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">count</span><span class="p">()</span>
<span class="c"># Output:</span>
<span class="c"># 3</span>
<span class="c"># The API automatically follows relationships as far as you need.</span>
<span class="c"># Use double underscores to separate relationships.</span>
<span class="c"># This works as many levels deep as you want; there's no limit.</span>
<span class="c"># Find all Choices for any question whose pub_date is in this year</span>
<span class="c"># (reusing the 'current_year' variable we created above).</span>
<span class="n">Choice</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">question__pub_date__year</span><span class="o">=</span><span class="n">current_year</span><span class="p">)</span>
<span class="c"># Output:</span>
<span class="c"># <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]></span>
<span class="c"># Let's delete one of the choices. Use delete() for that.</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">q</span><span class="o">.</span><span class="n">choice_set</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">choice_text__startswith</span><span class="o">=</span><span class="s">'Just hacking'</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
</pre></div>
<p></p><br/>
<p>
Much more can be done using this Database API. We will dig deeper into the subject later in the series.
</p><br/><br />
<h3>Django Admin</h3>
<p>
Django comes packaged with an admin site that can be used to manage the Data by the <strong>staff</strong> or <strong>clients</strong>. This site is <strong>not for site visitors</strong> to use rather for the site managers to interact with the data, like add, change and delete content. Any model can be added into this site for manipulation by the staff. This is done with very less configuration to plug any model into the Django admin site.
</p><br/>
<p>
Let's see how we use the admin site. First we’ll need to <strong>create a user</strong> who can login to the admin site. Run the following command:
</p><br/>
<p>
<pre>
<code>
python manage.py createsuperuser
</code>
</pre>
</p><br/>
<p>
Enter your desired <strong>username</strong> and press enter.
</p><br/>
<p>
<pre>
<code>
Username: admin
</code>
</pre>
</p><br/>
<p>
You will then be prompted for your desired <strong>email address</strong>:
</p><br/>
<p>
<pre>
<code>
Email address: awesome@email.com
</code>
</pre>
</p><br/>
<p>
The final step is to enter your <strong>password</strong>. You will be asked to enter your password twice, the second time as a confirmation of the first.
</p><br/>
<p>
<pre>
<code>
Password: **********
Password (again): **********
Superuser created successfully.
</code>
</pre>
</p><br/>
<p>
Now the superuser with access to everything in the admin site is created. Using this user credentials we can login into the admin site. But we have to <strong>start the server</strong> to be able to do so. To do that we run the following command:
</p><br/>
<p>
<pre>
<code>
python manage.py runserver
</code>
</pre>
</p><br/>
<p>
This starts a development server. Now open a Web browser and go to "/admin/" on your local domain - e.g., <a href="http://127.0.0.1:8000/admin/">http://127.0.0.1:8000/admin/</a> you will see the admin's login screen as follows:
</p><br/>
<p>
<img alt="alt text" src="https://django.cowhite.com/static/media/uploads/Tutorial/4%20-%20Database%20API%20and%20Django%20admin/django_admin_login.png" />
</p><br/>
<p>
<strong>Login with the superuser credentials</strong> you registered with previously. You will see the Django admin index page when logged in.
</p><br/>
<p>
<img alt="alt text" src="https://django.cowhite.com/static/media/uploads/Tutorial/4%20-%20Database%20API%20and%20Django%20admin/admin_default_home.png" />
</p><br/>
<p>
The <code>Group</code> and <code>Users</code> models are provided by <code>django.contrib.auth</code>, the authentication framework shipped with Django.
</p><br/>
<p>
But we don't see our Models here. For that we only need to do one thing: we need to tell the admin that <code>Question</code> objects are to be displayed in admin site. To do this, we add this line in <em>polls/admin.py</em> (or <em>admin.py</em> file in your choice of app).
</p><br/>
<p></p>
<div class="codehilite"><pre><span class="c"># Python code</span>
<span class="c"># polls/admin.py</span>
<span class="kn">from</span> <span class="nn">django.contrib</span> <span class="kn">import</span> <span class="n">admin</span>
<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">Question</span>
<span class="n">admin</span><span class="o">.</span><span class="n">site</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">Question</span><span class="p">)</span>
</pre></div>
<p></p><br/>
<p>
<img alt="alt text" src="https://django.cowhite.com/static/media/uploads/Tutorial/4%20-%20Database%20API%20and%20Django%20admin/admin_questions_added.png" />
</p><br/>
<p>
Now you can explore the whole admin site and get a feel for the same.
</p><br/></p>URLDispatcher2017-08-10T04:00:00+00:00srinath/blog/author/srinath/http://django.cowhite.com/blog/urldispatcher/<p>
Django comes packaged with a URL dispatcher which let's you design cool elegant URL scheme. It let's you design URLs the way you want with no limitations as such. Also there is no URL extentions such as .php, .html or .cgi, which means a much more beautiful URL.
</p>
<p><br />
These URLs must be mapped to a view somehow and that is where URLconf (URL configuration) comes into picture. The elegance of Django is that we achieve this mapping by just one line of Python code. Also this line of code much more than mapping a view to a URL which we will check out later in the blog.
</p>
<p><br /><br />
<h3>How Django processes a request</h3>
<p>
Before getting into details of URLconf lets understand how Django processes a request. According to the official documentation of Django a request is handled as follows:
</p>
<p>
1. Django determines the root URLconf module to use. Ordinarily, this is the value of the ROOT_URLCONF setting, but if the incoming HttpRequest object has a urlconf attribute (set by middleware), its value will be used in place of the ROOT_URLCONF setting.<br />
2. Django loads that Python module and looks for the variable urlpatterns. This should be a Python list of django.conf.urls.url() instances.<br />
3. Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.<br />
4. Once one of the regexes matches, Django imports and calls the given view, which is a simple Python function (or a class-based view). The view gets passed the following arguments:<br />
• An instance of HttpRequest.<br />
• If the matched regular expression returned no named groups, then the matches from the regular expression are provided as positional arguments.<br />
• The keyword arguments are made up of any named groups matched by the regular expression, overridden by any arguments specified in the optional kwargs argument to django.conf.urls.url().<br />
5. If no regex matches, or if an exception is raised during any point in this process, Django invokes an appropriate error-handling view. See Error handling below.
</p><br /><br />
<h3>Example</h3>
<p>
Listed below is a simple example of URLConf:
</p>
<p></p>
<div class="codehilite"><pre><span class="c"># Python code</span>
<span class="c"># myproject/myapp/urls.py</span>
<span class="kn">from</span> <span class="nn">django.conf.urls</span> <span class="kn">import</span> <span class="n">url</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">views</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blogs/2017/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">all_blogs_2017</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blogs/([0-9]{4})/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">blog_archive_year</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blogs/([0-9]{4})/([0-9]{2})/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">blog_archive_month</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blogs/(\S+)/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">blog_detail</span><span class="p">)</span>
<span class="p">]</span>
</pre></div>
<p></p><br />
<p>
Points to note:<br />
• To capture any value from the URL, you only have to put a parenthesis around it. We have put regexes in parenthesis which will be matched against the request URL and routed with the parameters captured from the URL.<br />
• There's no need to add a leading slash. It's <code>^blogs</code>, and not <code>^/blogs</code>.<br />
• Although optional, it's recommended to add the <code>'r'</code> in front of each regex string. It tells PYTHON that the string is "raw" and nothing should be escaped in the string.<br />
• If using the <strong>Class Based Views</strong> then the method calling would be <code>views.ViewClass.as_view()</code>.
</p><br />
<p>
Example requests:<br />
• A request to <code>https://www.example.com/blogs/2017/02/</code> would match the third entry in the list. Django would call the function <code>views.month_archive(request, '2017', '02')</code>.<br />
• <code>https://www.example.com/blogs/2017/2/</code> would not match any URL patterns, because the third entry in the list requires two digits for the month.<br />
• <code>https://www.example.com/blogs/2017/</code> would match the first pattern in the list, not the second one, because the patterns are tested in order, and the selected pattern (routed view) is first one to match. Here, Django would call the function <code>views.all_blogs_2017(request)</code>.<br />
• <code>https://www.example.com/blogs/2017</code> would not match any of these patterns, because each pattern requires that the URL end with a slash.<br />
• <code>https://www.example.com/blogs/very-interesting-blog/</code> would match the final pattern. Django would call the function <code>views.article_detail(request, 'very-interesting-blog')</code>.<br />
</p><br /><br />
<h3>Named Groups</h3>
<p>
In the above examples, we only had simple, unnamed regex groups to capture the parameters from the URL. It passed these parameters as positional arguments to the view. But a way more elegant and human readable format for passing these captured parameters is to pass them as <em>keyword</em> arguments to the view.
</p><br />
<p>
This is where the <strong>Named Groups</strong> comes into picture. In Python regular expressions, the syntax for named regular-expression groups is (?P<name>pattern), where name is the name of the group and pattern is some pattern to match.
</p><br />
<p>
Here’s the above example URLconf, rewritten to use named groups:</p>
<div class="codehilite"><pre><span class="c"># Python code</span>
<span class="c"># myproject/myapp/urls.py</span>
<span class="kn">from</span> <span class="nn">django.conf.urls</span> <span class="kn">import</span> <span class="n">url</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">views</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blogs/2017/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">all_blogs_2017</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blogs/(?P<year>[0-9]{4})/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">blog_archive_year</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blogs/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">blog_archive_month</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blogs/(?P<slug>\S+)/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">blog_detail</span><span class="p">)</span>
<span class="p">]</span>
</pre></div>
<p></p><br />
<p>
This accomplishes exactly the same thing as the previous example, with one minor difference. Instead of passing the captured parameters as positional arguments rather they will be passed as keyword arguments. For example:<br />
• A request to <code>/blogs/2017/02/</code> will call the function <code>views.blog_archive_month(request, year='2017', month='02')</code>.<br />
• A request to <code>/blogs/very-interesting-blog/</code> will call the function <code>views.blog_detail(request, slug='very-interesting-blog')</code>.
</p><br />
<p>
An important point to note here is that irrespective of what sort of match the regular expressions makes, the <strong>captured arguments are always sent as plain string</strong>. The <code>year</code> and <code>month</code> arguments are passed <code>'2017'</code> and <code>'02'</code> respectively, <strong>not</strong> <code>2017</code> and <code>02</code>.
</p><br/>
<h3>Important note:</h3>
<p>
You must not have both <em>named</em> and <em>unnamed</em> groups in the same URL matching string. If you do so, the unnamed arguments will be ignored.
</p>
<p>
The django documentation states the following as the matching/ grouping algorithm:<br />
1. If there are any named arguments, it will use those, ignoring non-named arguments.<br />
2. Otherwise, it will pass all non-named arguments as positional arguments.
</p><br /><br />
<h3>Specifying defaults for view arguments</h3>
<p>
A convenient trick is to specify default parameters for your views’ arguments. Here’s an example URLconf and view:</p>
<div class="codehilite"><pre><span class="c"># Python code</span>
<span class="c"># myproject/myapp/urls.py</span>
<span class="kn">from</span> <span class="nn">django.conf.urls</span> <span class="kn">import</span> <span class="n">url</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">views</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blog/single/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">blog_detail</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blog/single/(?P<slug>\S+)/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">blog_detail</span><span class="p">),</span>
<span class="p">]</span>
<span class="c"># Python code</span>
<span class="c"># myproject/myapp/views.py</span>
<span class="k">def</span> <span class="nf">blog_detail</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">slug</span><span class="o">=</span><span class="s">'home-page'</span><span class="p">):</span>
<span class="c"># Output the appropriate blog post according to the slug...</span>
<span class="o">...</span>
<span class="o">...</span>
</pre></div>
<p></p><br />
<p>
In the above argument both the URLs use the same view. But one uses that with an captured argument ans the other without. so to handle this we specify a default in the view so that, if the slug keyword isn't set, it will fallback to this default value.
</p><br />
<p>
So the first url will call the view with no arguments and thus will make the argument <code>slug</code> fallback to the default value of <code>'home-page'</code>.
</p><br />
<h3>Including other URLConfs</h3>
<p>
Django projects are split into apps and you can actually have a full hierarchy of apps and maintaining the urls for every view in every app in a project in a single file is very ugly way to go about it. So what Django does is it allows us to break up this dump of URLs into neat packets and them use the <code>include</code> function to include all these URLConfs into a single one. You could have a hierarchy of <code>includes</code> too.
</p><br />
<p>
Usually the URLconfs for any app is contained in itself and the then <code>include</code>d into the root URLConf in project <strong>urls.py</strong> file.
</p><br />
<p>
For example, here’s an excerpt of the URLconf for the Django website itself. It includes a number of other URLconfs:</p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">django.conf.urls</span> <span class="kn">import</span> <span class="n">include</span><span class="p">,</span> <span class="n">url</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
<span class="c"># ... snip ...</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^community/'</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">'django_website.aggregator.urls'</span><span class="p">)),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^contact/'</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">'django_website.contact.urls'</span><span class="p">)),</span>
<span class="c"># ... snip ...</span>
<span class="p">]</span>
</pre></div>
<p></p><br />
<p>
In the above <code>url()</code>s the <code>'django_website.aggregator.urls'</code> is the package name and the file name of the URLConf file in the app. In other words include URLconf from <strong>urls.py</strong> file from the package (app) <code>django_website.aggregator</code>. We could do it with our custom apps too.
</p><br />
<p>
Note that the regular expressions in this example don’t have a <code>$</code> (end-of-string match character) but do include a trailing slash. Whenever Django encounters <code>include()</code> (<code>django.conf.urls.include()</code>), it chops off whatever part of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.
</p><br />
<p>
This can be used to remove redundancy from URLconfs where a single pattern prefix is used repeatedly. For example, consider this URLconf:</p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">django.conf.urls</span> <span class="kn">import</span> <span class="n">url</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">views</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/history/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">history</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/edit/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">edit</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/discuss/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">discuss</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/permissions/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">permissions</span><span class="p">),</span>
<span class="p">]</span>
</pre></div>
<p></p><br />
<p>
We can improve this by stating the common path prefix only once and grouping the suffixes that differ:</p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">django.conf.urls</span> <span class="kn">import</span> <span class="n">include</span><span class="p">,</span> <span class="n">url</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">views</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/'</span><span class="p">,</span> <span class="n">include</span><span class="p">([</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^history/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">history</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^edit/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">edit</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^discuss/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">discuss</span><span class="p">),</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^permissions/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">permissions</span><span class="p">),</span>
<span class="p">])),</span>
<span class="p">]</span>
</pre></div>
<p></p><br />
<p>
Here all the view functions in <code>include()</code> will be passed the parameters of its parent <code>url()</code>. In this particular case the parameters <code>page_slug</code> and <code>page_id</code>. This works if you <code>include</code> a URLConf of an app as well.
</p><br /><br />
<h3>Reverse resolution of URLs</h3>
<p>
A common need when working on a Django project is the possibility to obtain URLs in their final forms either for embedding in generated content (views and assets URLs, URLs shown to the user, etc.) or for handling of the navigation flow on the server side (redirections, etc.)
</p><br />
<p>
It is strongly desirable to avoid hard-coding these URLs (a laborious, non-scalable and error-prone strategy). Equally dangerous is devising ad-hoc mechanisms to generate URLs that are parallel to the design described by the URLconf, which can result in the production of URLs that become stale over time.
</p><br />
<p>
In other words, what’s needed is a DRY mechanism. Among other advantages it would allow evolution of the URL design without having to go over all the project source code to search and replace outdated URLs.
</p><br />
<p>
The primary piece of information we have available to get a URL is an identification (e.g. the name) of the view in charge of handling it. Other pieces of information that necessarily must participate in the lookup of the right URL are the types (positional, keyword) and values of the view arguments.
</p><br />
<p>
Django provides a solution such that the URL mapper is the only repository of the URL design. You feed it with your URLconf and then it can be used in both directions:<br />
• Starting with a URL requested by the user/browser, it calls the right Django view providing any arguments it might need with their values as extracted from the URL.<br />
• Starting with the identification of the corresponding Django view plus the values of arguments that would be passed to it, obtain the associated URL.
</p><br />
<p>
The first one is the usage we’ve been discussing in the previous sections. The second one is what is known as reverse resolution of URLs, reverse URL matching, reverse URL lookup, or simply URL reversing.
</p><br />
<p>
Django provides tools for performing URL reversing that match the different layers where URLs are needed:<br />
• In templates: Using the URL template tag.<br />
• In Python code: Using the reverse() function.<br />
• In higher level code related to handling of URLs of Django model instances: The get_absolute_url() method.
</p><br />
<h4>Example</h4>
<p>
Consider this URLconf entry:</p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">django.conf.urls</span> <span class="kn">import</span> <span class="n">url</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">views</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
<span class="c"># ...</span>
<span class="n">url</span><span class="p">(</span><span class="s">r'^blogs/([0-9]{4})/$'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">blog_archive_year</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">'blogs-archive-year'</span><span class="p">),</span>
<span class="c"># ...</span>
<span class="p">]</span>
</pre></div>
<p></p><br />
<p>
You can obtain the fully formed URL for this <code>url()</code> in <strong>template code</strong> by using:</p>
<div class="codehilite"><pre>{# with a value #}
<span class="nt"><a</span> <span class="na">href=</span><span class="s">"{% url 'blogs-archive-year' 2017 %}"</span><span class="nt">></span>2017 Blogs<span class="nt"></a></span>
{# with a context variable #}
<span class="nt"><ul></span>
{% for yearvariable in year_list %}
<span class="nt"><li><a</span> <span class="na">href=</span><span class="s">"{% url 'blogs-archive-year' yearvariable %}"</span><span class="nt">></span>{{ yearvariable }} Blogs<span class="nt"></a></li></span>
{% endfor %}
<span class="nt"></ul></span>
</pre></div>
<p></p><br />
<p>
For named groups you could do the following:</p>
<div class="codehilite"><pre>{# with a value #}
<span class="nt"><a</span> <span class="na">href=</span><span class="s">"{% url 'blogs-archive-year' year=2017 %}"</span><span class="nt">></span>2017 Blogs<span class="nt"></a></span>
</pre></div>
<p>where <code>year</code> is the group name.
</p><br />
<p>
In <strong>Python code</strong> we could get the reverse URLs as follows:</p>
<div class="codehilite"><pre><span class="kn">from</span> <span class="nn">django.urls</span> <span class="kn">import</span> <span class="n">reverse</span>
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponseRedirect</span>
<span class="k">def</span> <span class="nf">redirect_to_year</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="c"># ...</span>
<span class="n">year</span> <span class="o">=</span> <span class="mi">2016</span>
<span class="c"># ...</span>
<span class="k">return</span> <span class="n">HttpResponseRedirect</span><span class="p">(</span><span class="n">reverse</span><span class="p">(</span><span class="s">'blogs-archive-year'</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">year</span><span class="p">,)))</span>
</pre></div>
<p></p><br /></p>Models and Migrations2017-08-03T09:53:50+00:00srinath/blog/author/srinath/http://django.cowhite.com/blog/models-migrations-and-django-admin/<h3>Setting up Database</h3>
<p>
Before we start with models let's understand how to setup database to work with Django. Django comes pre bundled and ready to work with SQLite database, which for development and for very small lightweight websites would be enough to wor with, but if the scale of the website or the user-base of the website is even moderately high, SQLite is definitely not enough.
</p>
<p><br />
<p>
Other than SQLite Django can work with the following Databases:<br />
• MySQL<br />
• Postgres<br />
• Oracle<br />
</p><br />
<p>
Let's see how to setup the database for each of the above backends.
</p><br /><br />
<h4>SQLite</h4>
<p>
The settings for any database is registered in the <strong>settings.py</strong> file in <em>myprojectname/myprojectname/</em> directory. We register them by listing the settings for the database as a Python dictionary. It is a nested dictionary whose contents map a database alias to a dictionary containing the options for an individual database.
</p><br />
<p>
For the SQLite backend we have the following setting, which is probably the simplest:</p>
<div class="codehilite"><pre>DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'awesomedb',
}
}
</pre></div>
<p></p><br />
<p>
Please note that the dictionary is assigned to a variable named <code>DATABASES</code>. It should be named the same. Also the <code>'NAME'</code> property specifies the SQLite database filename that should be used to store the backend data.
</p><br /><br />
<h4>MySQL, Postgres, Oracle</h4>
<p>
When connecting to other database backends, such as MySQL, Oracle, or PostgreSQL, additional connection parameters will be required, viz, database username and password, database host URL and port etc.
</p><br />
<p>
Also unlike SQLite database, we need to install certain dependencies for Django to be able to connect to these backends.<br />
• If you’re using PostgreSQL, you’ll need the <a href="http://initd.org/psycopg/">psycopg2</a> package (2.5.4 or higher).<br />
• If you’re using MySQL, you’ll need a DB API driver like <a href="https://pypi.python.org/pypi/mysqlclient">mysqlclient</a>. Also MySQL version should be 5.5 or higher.
• If you’re using Oracle (v11.2 or higher supported), you’ll need a copy of <a href="https://oracle.github.io/python-cx_Oracle/">cx_Oracle</a> (version 5.2 or higher).</p>
<p></p><br />
<p>
Given below is the example for connecting a <strong>PostGres</strong>:
</p><br />
<p></p>
<div class="codehilite"><pre>DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'awesomedb',
'USER': 'awesomedbuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
</pre></div>
<p></p><br />
<p>
For connecting to other Databases, edit the value for <code>'ENGINE'</code> as follows:<br />
</p><br />
<table>
<tbody>
<tr>
<th style="padding-left: 5px; padding-right: 5px;border-bottom: 1px solid;">
Database
</th>
<th style="padding-left: 5px; padding-right: 5px;border-bottom: 1px solid;">
<code>'ENGINE'</code> value
</th>
</tr>
<tr>
<td style="padding-left: 5px; padding-right: 5px;">
MySQL
</td>
<td style="padding-left: 5px; padding-right: 5px;">
<code>'django.db.backends.mysql'</code>
</td>
</tr>
<tr>
<td style="padding-left: 5px; padding-right: 5px;">
ORACLE
</td>
<td style="padding-left: 5px; padding-right: 5px;">
<code>'django.db.backends.oracle'</code>
</td>
</tr>
</tbody>
</table><br /><br />
<h4>Timezone Setting</h4>
<p>
While you are setting up the <strong>myprojectname/settings.py</strong>, set <code>TIME_ZONE</code> to your timezone. <code>TIME_ZONE</code> should be a string representing the time zone. Click here for the list of <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">timezones</a>.
</p><br /><br />
<h4>Installed apps</h4>
<p>
Note the <code>'INSTALLED_APPS'</code> setting at the top of the file. This holds the names of all the Django applications activated in this particular Django project. As we have discussed above, apps can be used in multiple projects and can also be packaged and distributed for use by others in their projects.
</p><br />
<p>
The default <code>'INSTALLED_APPS'</code> contain the following apps. These apps are prepackaged apps that come with Django.<br />
• <code>django.contrib.admin</code> -> The admin site. We will look in to it ahead in this blog.<br />
• <code>django.contrib.auth</code> -> The authentication system for Django.<br />
• <code>django.contrib.contenttypes</code> -> A framework for content types.<br />
• <code>django.contrib.sessions</code> -> The sessions framework.<br />
• <code>django.contrib.staticfiles</code> -> Framework for managing static assets files.
</p><br />
<p>
<strong>Important Note</strong>: Some of the above applications make use of database. And right now although you may have setup the SQL server (no setting up needed for SQLite.), the database tables needed for these applications aren't migrated into them. So lets migrate them first. To do that, run the following command:
</p><br />
<p>
<pre>
<code>
python manage.py migrate
</code>
</pre>
</p><br /><br />
<h3>Creating a Model</h3>
<p>
Models are nothing but database layouts with additional metadata. Let's see how to create our first Models in Django.
</p><br />
<p>
In our simple poll app, we’ll create two models: Question and Choice. A Question has a question and a publication date. A Choice has two fields: the text of the choice and a vote tally. Each Choice is associated with a Question.
</p><br />
<p>
These concepts are represented by simple Python classes. Edit the polls/models.py file so it looks like this:
</p><br />
<p></p>
<div class="codehilite"><pre><span class="c"># Python Code</span>
<span class="c"># polls/models.py</span>
<span class="kn">from</span> <span class="nn">django.db</span> <span class="kn">import</span> <span class="n">models</span>
<span class="k">class</span> <span class="nc">Question</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
<span class="n">question_text</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">200</span><span class="p">)</span>
<span class="n">pub_date</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="s">'date published'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Choice</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
<span class="n">question</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Question</span><span class="p">,</span> <span class="n">on_delete</span><span class="o">=</span><span class="n">models</span><span class="o">.</span><span class="n">CASCADE</span><span class="p">)</span>
<span class="n">choice_text</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mi">200</span><span class="p">)</span>
<span class="n">votes</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">IntegerField</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</pre></div>
<p></p><br />
<p>
Let's dissect this block of code and understand the significance of each line.
</p><br >
<p>
Both the models are represented by a class that has <code>django.db.models.Model</code> as its parent class. And the fields (or columns, in SQL terms) are represented by class variables.
</p><br />
<p>
For the fields that are supposed to be persisted are represented by an instance of a subclass of the <code>Field</code> class - e.g., <code>CharField</code> for character fields, <code>DataTimeField</code> fot datetimes and <code>IntegerField</code> for integer fields and so on.
</p><br />
<p>
The name of each <code>Field</code> instance (e.g. <code>question_text</code> or <code>pub_date</code>) is the field’s name, in machine-friendly format. You’ll use this value in your Python code, and your database will use it as the column name.
</p><br />
<p>
Some <code>Field</code> classes have required arguments. <code>CharField</code>, for example, requires that you give it a <code>max_length</code>. That’s used not only in the database schema, but in validation, as we’ll soon see. They also have optional arguments; in our case we have set the <code>default</code> value of <code>votes</code> to 0.
</p><br />
<p>
Finally, note a relationship is defined, using <code>ForeignKey</code>. That tells Django each <code>Choice</code> is related to a single <code>Question</code>. Django supports all the common database relationships: many-to-one, many-to-many, and one-to-one.
</p><br />
<h3>Migrating the Models</h3>
<p>
Django apps are basically "pluggable" modules. So here we have given Django a lot of information with our models.py code. And based on this information Django <strong>Creates the database schema</strong> and a <strong>Python wrapper API</strong> around this database for accessing the data from the database.
</p><br />
<p>
But for all this to happen we need to tell our Django project that we want the <code>polls</code> app to be installed. And to do that we add a reference to its configuration class in the <code>'INSTALLED_APPS'</code> setting we saw earlier. The <code>PollsConfig</code> class is in the <em>polls/apps.py</em> file, so its dotted path is <code>'polls.apps.PollsConfig'</code>. Edit the <em>mysite/settings.py</em> file and add that dotted path to the <code>INSTALLED_APPS</code> setting. It’ll look like this:
</p><br />
<p></p>
<div class="codehilite"><pre># Python Code
# myprojectname/settings.py
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
</pre></div>
<p></p><br />
<p>
This tells Django to include the <code>polls</code> app. Now let's make the migration files:
</p><br />
<p>
<pre>
<code>
python manage.py makemigrations polls
</code>
</pre>
</p><br />
<p>
You should see something similar to the following:
</p><br />
<p></p>
<div class="codehilite"><pre>Migrations for 'polls':
polls/migrations/0001_initial.py:
- Create model Choice
- Create model Question
- Add field question to choice
</pre></div>
<p></p><br />
<p>
What this does is notify Django that certain changes have been made in the models. These changes are stored in a <em>migration</em> file. This migration file is used to change the database schema. These migrations are just regular files with instructions to change the schema. We could read the migration if needed. It will be a file similar to <em>polls/migrations/0001_initial.py</em>. Reading them is not a compulsion, rather it is just to quench your thirst of curiosity.
</p><br />
<p>
These migration files do not include actual SQL statements rather it includes a intermediate python code which is used to generate the SQL commands. To view the actual SQL statements we could run the following command:
</p><br />
<p>
<pre>
<code>
python manage.py sqlmigrate polls 0001
</code>
</pre>
</p><br />
<p>
Note that the <code>0001</code> denotes the prefix of <strong>0001_initial.py</strong>
</p><br />
<p>
Let's actually write the changes to database now. This can be done by running the following command:
</p><br />
<p>
<pre>
<code>
python manage.py migrate
</code>
</pre>
</p><br />
<p>
This actually applies the changes into the database by running the migration. Django has a note of all applied migrations and runs them against the database only if not yet applied. Thus essentially syncing the changes to your database based on you your changes in Models.
</p><br />
<p>
The reason that there are separate commands to make and apply migrations is because you’ll commit migrations to your version control system and ship them with your app; they not only make your development easier, they’re also usable by other developers and in production.
</p><br />
<p>
So, the steps to remember for changing the database schema is as follows:<br />
• Change your models in <em>models.py</em> file.<br />
• Run <code>python manage.py makemigrations</code> to create migrations for the changes made.<br />
• Run <code>python manage.py migrate</code> to apply those changes to the database.
</p><br /></p>