TextField will return a scrollable paragraph in the admin.
auto_now_add generates automatically a timestamp when a news is created.
auto_now updates the timestamp every time you change the news.
Concerning the city attribute which is a many to one relationship: every piece of news is linked to one city, two pieces of news can have the same city.
It's standard that the name of a model (not class) is singular, and django automatically puts it to plural for external use. However here, News is a singular/plural english name, so we need to make sure Django does not add a second 's' (Newss) by overriding verbose_name_plural
Finally, make your migrations and migrate. To do this run the following commands in your shell:
In the shell display the table (in case of psql \d) and check the existence of your model. More info here
Add permissions to a group (~10 min)
Users that are in groups need permission to access the Model. If you don't have a group yet, you can create one by
clicking on group on the admin web site. We can now add permissions to them that will be automatically added when
you deploy.
# File: "our_django_project/users/apps.py"from django.apps import AppConfigfrom django.contrib.admin import sitefrom django.db.models.signals import post_migrate# This function takes a group and a model and adds all the permissions (read, update, delete) of this model to the group
defadd_model_permissions(group,model,ContentType,Permission): content_type = ContentType.objects.get_for_model(model) permissions = Permission.objects.filter(content_type=content_type)for permission in permissions: group.permissions.add(permission)
You can than create a migration to add the groups permissions when the migrations are run
Create an empty migration:
pythonmanage.pymakemigrations--emptyusers
Then fill in your migration like so:
from django.db import migrations# This function takes the model News and adds the permissions to the group Mayor Admindefadd_group_permissions(sender,using,apps,**kwargs): Group = apps.get_model("auth", "Group") Permission = apps.get_model("auth", "Permission") ContentType = apps.get_model("contenttypes", "ContentType") News = apps.get_model("publications", "News")#Add this line#If the group Mayor Admin doesn't exist, this piece of code creates it.if Group.objects.using(using).filter(name='Mayor Admin').exists(): group = Group.objects.get(name='Mayor Admin')else: group = Group.objects.using(using).create(name='Mayor Admin')add_model_permissions(group, News, ContentType, Permission)#Add this second lineclassMigration(migrations.Migration): dependencies = [ ('users','0001_initial'), ] operations = [ migrations.RunPython(add_group_permissions), ]
Then run
pythonmanage.pymigrate
What you can check!
Add the News model to the admin (~5 min)
We now need to add the model to the admin back-office.
If you don't add the list_display property, the default column title in the admin will be the result of the magic method str returned in the model (you can read more here). list_display allows you to add several columns to the admin interface.
What you can check!
Note: you can learn how to add other configuration to your admin by reading the official documentation
Serialize the News you get from the database (~5 min)
Serializers translates Django models into other formats(json, xml). In our project want to get a JSON response. Check out the official Django doc for more info.
# File: "our_django_project/publications/serializers.py"from.models import Newsfrom rest_framework import serializersclassNewsSerializer(serializers.HyperlinkedModelSerializer):id= serializers.IntegerField(source='pk') city = serializers.StringRelatedField(many=False, source="city.pk") #We need this to get the primary key of the city that is attached to this news
classMeta: model = News fields = ('title','description','created_at','updated_at','city','id') #All the fields you wish to get
Create a News ViewSet (~5 min)
ViewSets will allow you to concentrate on modeling the state and interactions of the API, and leave the URL construction to be handled automatically
Note: Check out the Django doc for more info ViewSets
# File: "our_django_project/publications/viewsets.py"from.models import Newsfrom rest_framework import viewsetsfrom.serializers import NewsSerializer#This is an example of filtering the pieces of news with the city-id like this: /?city-id=5classFilterByCity(object):defget_queryset(self): #You need to override the default get_queryset method queryset =super().get_queryset() city_id = self.request.query_params.get('city-id')# This filters the queryset by city (if there is a city)if city_id isnotNone: queryset = queryset.filter(city=city_id)return querysetclassNewsViewSet(FilterByCity,viewsets.ModelViewSet): queryset = News.objects.all() serializer_class = NewsSerializer
The NewsViewSet class will now inherit both classes FilterByCity viewsets.ModelViewSet from right to left. Therefore, the FilterByCity get_queryset method will override the ModelViewSet one.
Note: You can also use automatically generated filters (have a look here)
Mount the News ViewSet to an endpoint using a router (~5 min)
Django routers will allow you to easily generate different routes from your ViewSet (GET, POST, ...)
# File: "our_django_project/config/router.py"from rest_framework import routersfrom our_django_project.users.viewsets import UserViewSetfrom our_django_project.locations.viewsets import CityViewSetfrom our_django_project.publications.viewsets import NewsViewSet #Add this line# Routers provide an easy way of automatically determining the URL conf.router = routers.DefaultRouter()router.register(r'users', UserViewSet)router.register(r'locations/cities', CityViewSet)router.register(r'publications/news', NewsViewSet)#Add this one too
Note:Here is the Django doc if you want to learn more about Django routers
What you can check!
[ {"title":"Reading the article","description":"Hello, I am glad I read this article!","created_at":"2017-11-08T15:31:30.597524Z","updated_at":"2017-11-08T15:31:30.597555Z","city":"66","id":2 }, {"title":"Tutorial","description":"I followed the tutorial to create a new model","created_at":"2017-11-08T15:33:28.834694Z","updated_at":"2017-11-08T15:33:28.834721Z","city":"66","id":3 }, {"title":"Les Français adorent !","description":"J'ai lu cet article, il m'a aidé à faire mon premier modèle, youhouu !","created_at":"2017-11-08T15:20:33.457740Z","updated_at":"2017-11-08T16:54:19.322703Z","city":"5","id":1 }]
[ {"title":"Les Français adorent !","description":"Je suis française et j'ai lu cet article, il m'a aidé à faire mon premier modèle, youhouu !","created_at":"2017-11-08T15:20:33.457740Z","updated_at":"2017-11-08T16:54:19.322703Z","city":"5","id":1 }]