Lets see how to add pagination to viewset. As will all other things in django, this is super easy
Assuming you have already done the the tutorial P6 – Django – Viewsets it is possible that we might need pagination on some of the rest calls. So we may have a lot of data on the server and sending it all at once back to the client may not be required and may not be the efficient way to handle the data. The client on the other hand might need only a handful of data and would not want all the data which will become difficult to process. So Lets see how do we set up pagination on view sets.
lets take example of rest services which returns “Ads” and it may have thousands of ads. At any point of time the client will need only a handful of them to process. So the client must be able to pass the rest service some parameter identifying the page number it desires.
For our example. We create a pagination.py file and add below content.
from rest_framework.pagination import PageNumberPagination
class PaginationMeta(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 10000
Here we have set three parameters. One is the “page_size” which means the amount of data the server will send if requested with page number i.e with parameter “page” . The next is “page_size_query_param” which can be used if want a specified number of records to be retrieved and override the page_size. “max_page_size” which is the max page size for our request.
The next step is to set this class in our viewset as below.
from django.shortcuts import render
from .models import Ads
from .serializers import AdsSerializer
from rest_framework import viewsets
from .pagination import PaginationMeta
# Create your views here.
class AdsView(viewsets.ModelViewSet):
queryset = Ads.objects.all()
serializer_class = AdsSerializer
pagination_class = PaginationMeta
Here we set the pagination_class to the PaginationMeta we created. And this is all we will have to do to set up pagination. I am providing other classes required for this example.
from django.db import models
# Create your models here.
class Ads(models.Model):
category = models.CharField(max_length=50)
city= models.CharField(max_length=50)
email = models.CharField(max_length=50)
brand = models.CharField(max_length=50)
make = models.CharField(max_length=50)
capacity = models.CharField(max_length=50)
desc = models.CharField(max_length=150)
price = models.FloatField(max_length=20)
from rest_framework import serializers
from .models import Ads
class AdsSerializer(serializers.ModelSerializer):
class Meta:
model = Ads
fields = ['id','category', 'city','email','brand','make','capacity','price','desc']
from rest_framework.routers import DefaultRouter
from . import views
from django.urls import path, include
router = DefaultRouter()
router.register('ads', views.AdsView)
urlpatterns = [
path('', include(router.urls))
]
Now we have set the url pattern for our views to “/ads” so to access the views so a call to http://localhost:8000/api/ads/ will return the first page as below.
As you can see, it has returned with the first page and also various others attributes to navigate to next page. We can jump to any page we wish by providing the page parameter to the url e.g.http://localhost:8000/api/ads/?page=4
Please let us know if you liked this post and if it helped you. Thank you for spending time reading my post.
Step 2 – Create a new django project “django-postgres”
django-admin startproject django-postgres
Step 3 – Navigate to project directory “django-postgres” to Install django restframework
cd django-postgres
pip install djangorestframework
Step 4 – Install psycopg2 – Adapter for postgres
pip install psycopg2
Step 5 – now lets create a new app
python manage.py startapp models
Step 6 – Add the app to the installed apps of your project in the file settings.py. You will find it under “<root directory>/django-postgres”
'models.apps.ModelsConfig'
settings.py
Step 7 – Update the databases section in the settings.py file of the project to have postgres database details. Name represents database name and other parameters are self explanatory. Update all the details.
Step 8 – Lets create a model in the models app so that we can test the database configuration. In the models app directory update below files. Create files where they are not already present.
<root_dir>/django_postgres/models/models.py
from django.db import models
class Company(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=100)
email = models.CharField(max_length=50)
Here we have create a simple model class named Company
Create a new file serializers.py file in the models app <root_dir>/django_postgres/models/serializers.py
from rest_framework import serializers
from .models import Company
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ['id', 'name', 'address', 'email']
in the views.py file of models app, add following content. Here we are using viewsets to configure our views for company
<root_dir>/django_postgres/models/views.py
from rest_framework import generics, viewsets
from .models import Company
from .serializers import CompanySerializer
class CompanyViewSet(viewsets.ModelViewSet):
queryset = Company.objects.all()
serializer_class = CompanySerializer
Create/Update urls.py file to create url mapping of company views
<root_dir>/django_postgres/models/urls.py
from django.urls import path, include
from . import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('company', views.CompanyViewSet)
urlpatterns = [
path('', include(router.urls))
]
update the urls.py file of the project django_postgres. Add a new entry as below in the urlpatterns section
path('api/', include('models.urls')),
Step 9 – We are pretty much done and now is the time to test our project. I have updated the project in the git url mentioned at the start of the page. If something is not working, please do write in comments or try and download the project and execute.
Execute “makemigrations” and “migrate” command as below
Now try and add some new elements and see the results. You can also go to postgres database and you should find models_company table created with the entries you have created.
Lets begin with creation of the project using command django-admin startproject djangoauth. I will be using pycharm to edit files. You can edit in pycharm or anyother ide or your choice.
Step 2 –
On the terminal, in our project root directory, execute commands “python manage.py makemigrations” and “python manage.py migrate”
Step 3 – Lets create a template directory where we will place our html files. I have created a templates directory in the root of the project. You may create the same structure. Also we need to register this directory in the settings.py file in the templates object. Against the DIRS add the following path. This will register our templates directory with the django project
'DIRS': [os.path.join(BASE_DIR, 'templates')],
Lets add a home page for our application by adding home.html under the templates directory and add some sample content as below.
Step 4 – Add url mapping to enable authentication and the home page in the urls.py of djangoauth project (/djangoauth/djangoauth) file. The “django.contrib.auth.urls” is where we set up authentication
from django.contrib import admin
from django.urls import path, include
from django.views.generic.base import TemplateView
urlpatterns = [
path('admin/', admin.site.urls),
]
urlpatterns += [
path('', include('django.contrib.auth.urls')),
path('', TemplateView.as_view(template_name='home.html'))
]
Step 5 – Now lets run and check what is happening on the browser. Run our application by execution “python manage.py runserver”. You should see following code
Step6 – Django provides an admin page where we can add modify users. We will first create a superuser so that we can add more users to log-in. To create a superuser execute command “python maange.py createsuperuser”
To login with this user, On the browser navigate tohttp://localhost:8000/admin, this will show up the login page. Login with the user created above, you should see the below page
Now create a new user by clicking on add button. you will be presented with below page. fill in the details and click save. On the next page you can just click save.
Step 7 Next up is we need to setup the login page. Django looks for login page under the registration directory of templates. So we create a login.html file as below in templates/registrations directory.
Next we update our home.html to show login and logout. Copy the below content to home.html
{% if user.is_authenticated %}
<h1>Welcome to home</h1>
{% else %}
<h1> Login to the application</h1>
{% endif %}
<a href = "http://localhost:8000/login/">login</a>
{% if user.is_authenticated %}
<a href = "http://localhost:8000/logout/">logout</a>
{% endif %}
Add below variables to settings.py file. Here we are setting the login url and where should it redirect upon login and logout. Save the file and now navigate to http://localhost:8000/
Click on login and enter with the user you created to see below page. And now you can click on logout to check if it works. It should take you back to the login screen.
In this tutorial we will go through integration of django and react in just 10 min
There aren’t many tutorials clearly identifying changes required in django app to run with a react app. Most tutorials seem complex and steps mentioned are often are not necessary. We will look at steps to integrate django rest service with a react web application and all this will be served from the django project. We will also demonstrate hot deployment of react changes when working in django when we are developing and there are constant changes that we would want to make to the UI pages and look at result of those changes. You wont believe, it hardly takes 10 mins.
I am making a few assumptions here.
Django is installed
DjangoRestFramework is installed
Basic understanding of Django
npm and npx are installed
PyCharm IDE – Not mandatory but recommended
The above installations are fairly simple and extremely easy. We wont go into details of those installations as you would find bunch of those on google search
Lets begin by creating a django project. As you can see below, I have created a new django project “DjangoReactProject“
If you open the directory, you should find below files/directories created by django
Step 2 – Create App
Next up we are going to create a new Django app, lets call this as service as we are going to serve rest calls from this service.
Step 3 – Register the app & Create url mapping
I have opened my project in pycharm but you may as well edit the files in any editor. The current project structure should look like
Next is to register the service app to the project, this is done by adding the app config in the settings.py file of the project.
Now that we have registered our app to the project. Lets add a function in the views.py file of our app. This function is what we will respond from the service app for our project. If you see below In the views.py file, I have added a new function which responds with a dummy json string having name and city attributes.
Next, Create a urls.py file in the our service app and create a mapping between a default http request with the function we have created just now.
Step 4 – Test the url
Now lets run our project to see if we receive response for our mapped url. Run the command “python manage.py runserver” and you should see below console output.
Lets create a react app inside our project folder with npx. This should take a few mins. This will download all the packages required for react. Once this is complete, You should see directory structure like below
Steps 6 – Add Component and Update App.js
Lets create a new directory named “components” under src in our react app just created and create a new file “MyComponent.js” and add below content .
This is a very basic code in React and most of you must already understand what is going on here.
We have created a new React component and initialized state of the component with name and city. In the render function, we are passing an html with the content of the state inside a div element. We have overriden the component “componentDidMount” in which we are making an http request to the url we created in Django and setting it into the state of the component
Now lets add this component to App.js file in the react application under the src folder. React must have pre-populated some content. Remove all of that and copy below code to the App.js file
import React from 'react';
import logo from './logo.svg';
import './App.css';
import MyComponent from './components/MyComponent.js'
function App() {
return (
<div className="App">
<h1>React App - Served from Django</h1>
<MyComponent/>
</div>
);
}
export default App;
Step 7 – Run the react build
Navigate to the react app folder and create react build by running npm run build. A build directory will be created after successful execution of the build with all the files required for the react app. The starting point of the application being index.html
Step 8 – Configure Django to serve react build
We now just need to point Django to the build directory of react so that it starts serving from there. In our DjangoReactProject directory present in the root of our project, navigate to settings.py
Find Templates in the settings.py file and add the build directory of our react application as show in the screenshot in the DIRS. We are telling python where to find templates in the react application
In the same file add a new variable “STATICFILES_DIRS” if not present already and add variable which points to the static content of the react app as below
Now run our django server and it should start serving our react application and call the rest service /api to render the response
C:\DjangoReactProject>python manage.py runserver
This should deploy our django app with react @ http://localhost:8000/. Navigate to the url to see below page.
Step 9 – Hot Deployment
So the above is fine structure to deploy our react application once all of our react code is ready, but during development it is going to be very difficult to always having to build our react app for small changes in our react app. So to overcome this, we have to make a small change in the react app so that when we are developing all the requests are redirected to django app.
So when we are developing we will run the inbuild react server to server our react application, which will redirect calls to django server when required.
To configure this we just need to add proxy configure in the package.json file of the react app.
Here we have given the address of server
"proxy": "http://127.0.0.1:8000",
Once this is done, lets run the react server by running command “npm run start”. This will start the react application @ http://localhost:3000/ and you should see the below page. Any changes to react will be hot deployed for development.
At this point any changes in the Django or the react app are hot deployed and we can make changes to quickly see the results.
Ohh. We have still not reached Step 10, that was really easy. Let us know if you have any queries or like the page if you have like this tutorial, post any feedback if you have. Thank you!
Lets see how to respond with an html in django. Till now we have seen how to respond to a rest call with a json response. But we will also need to respond to a request with an html/css/javascript. Lets create a small django app to demonstrate the same.
Open command terminal and create a directory “TemplateDjangoProject” and navigate into that project
Step 2
First install Django with command “pip install django”
Step 3
Create a project with command “django-admin startporject testproject . “
Step 4
Now create app with command “python manage.py testapp”
Step 5
Add the newly created app in the settings.py file of the testproject folder under the installed_apps array as below to register our new app
Step 6
Now, create a new folder templates under the app testapp folder and create index.html file with content as below
Step 7
Create a function in the views.py file of the app testapp as below
Step 8
update the urls.py(create if not present) file as below. Here we are mapping our url to the function we created in the views.py file in the previous step
Step 9
Now update the urls.py of the our testproject to include the urls created in our app.
Step 10
We are done. Now run the server executing the command “python manage.py runserver” and then navigate to the deploy url to see below response from the server
GIT LINK – https://github.com/letsblogcontent/SampleRestProject/upload/master So till in the previous tutorials we have different ways to configure views and models but we have seen basic examples and there were no relationships between models which hardly happen in the real world. In most cases models have relationship between each other.
Lets see how to create relationship between our product and company model. So earlier we created two models, product and company but there was no relationship between them. So ideally each product is produced by a company. So there is one to one relation between a product and company. a product is associated with one and only one company.
Step 1
Lets implement this in our models. Before starting lets flush out the data we created from our previous tutorials using the command “python manage.py flush”
#terminal
Step 2
Now update our models to create the relationship between Product and Company.
We have here created a company variable in the Product model and used the ForeignKey Api to in the models class to create the relationship. We have also mentioned what should happen when a record is deleted using the on_delete parameter. In our case we do not want anything to happen in the company model when a product record is deleted. The parameter blank = False means that the field cannot be blank. There are several other parameters that we can set for a field. You can check them out at the django documentation
Update the product serializer to have company
There is no change required in the view class and also no change required in the urls.py file. Now lets see how does the database table of product look like.
See, a new column company_id is added to the product table which refers to the primary key of the company table.
Step 3
Lets add a company and try adding a product afterwards and with a company associated with it.
We add a new company
Notice that when we retrieve we receive only the company id and not the entire company object with details. Lets make a simple change to retrieve entire company object details instead of the id.
update the serializer of the product to with a reference to company serializer as below.
Now lets see the output.
We can add different relationships other than Foreign key, like the onetoone of manytomany. The implementation is similar to the above with change in the api. Rest of the things will mostly remain the same
Django also provide a more higher level of abstraction for the model and the views called as ViewSets. This abstractions allows developer to concentrate on the modelling and the state rather than url construction. It is very slightly different than the view creating view classes but with viewsets we have to write less code and it makes more sense as lot of the repetative code is abstracted and we can choose to overwrite if required.
Step 1
Lets continue from where we left and create a new model known as User in models.py file and execute makemigrations and migrate command to create this new model.
#models.py
Once the model is created run the command “python manage.py makemigrations” and then “python manage.py migrate“
Step 2
Similar to previous tutorials, we create a standard serializer
#serializers.py
Step 3
Now lets create a new viewset for User model as below by extending the ModelViewSet Class.
#views.py
remember with class based views, we had to create view classes for list views and the model view. But here we are creating only one viewset class.
Step 4
Update the urls.py file as below. Notice that we just have to register the viewset to router and all the urls configuration will be abstracted for us and will be handled by the Router. So this has reduced our code of creating list view and also creating a different url patterns
#urs.py
Step 5
Now lets test and see it in action. So this should serve our purpose for time being. We will look at different scenarios and ways to handle in the next tutorial
So till now we have seen all things that we need to write or configure to make a new rest api and configure new endpoints. A lot of code in a model based structure is repetitive if you look closely. A model needs to respond to GET , POST, PUT , DELETE requests etc through a view. Mixins allow us to fire a new endpoint with all the default functions really fast and we dont need to write all the code that we wrote in previous tutorials. So all we have to do is create our model, serializer and map it to a url. The view also needs update but its very simple, a lot of handling will be done by the framework. Let look at an example.
Step1
Suppose we need an endpoint for company. So create a model and serializer like below
models.pyserializer.py
Step 2
Now mixins provides a bunch of different ways to configure your view. We will look at one of them. But you can explore other configurations as well based on your need.
Create two classes in the views.py file, one to list all the companies and accept a post request to add a company and other to access a single company or delete a single company which will handle GET, PUT, DELETE request.
Notice the mixins used in the CompanyListView, one is the ListModelMixin andother is the CreateModelMixin Mixin. One to list the data and other to create. All we do here is tell the class where to fetch the objects from and which is the serializer class using the queryset variable and the serializer_class variable. Then we have defined two methods GET and POST and used the list and create methods from the mixins to list or create a new object.
Now let looks at more concise way of writing the above functionality on the company view with which we can retrieve a single company or delete a company.
view.py
Notice we have extended from RetrieveDestroyAPIView class from generics. This will abstract everything for us and all that we have to provde is the queryset and serializer_class and its done.
So we have now configured the CompanyView and CompanyListView. Now lets add them to the urls.py file.