This article walks you through the steps of a beginner developing a coupon distribution service for the iPhone with a RESTful API and swift. It is a very detour implementation because it was implemented while examining the technical elements one by one.
In the previous Implementing API authentication function by JWT in Django Rest Framework, the authentication function was implemented, and it became an API that can withstand practical use to some extent. However, the current situation is that the current coupons are only textual information and are weak in terms of visuals.
Therefore, this time, we will use a package called "Pillow" for handling image files in Django, so that coupon images can also be distributed by API.
Even if you create a new API that handles images with Django, the part related to "Pillow" is the same, so I hope it will be helpful.
Since my environment is a virtual environment of python with pipenv, after entering the shell of pipenv, install pillow as follows. After installation, check the Pipfile to confirm that pillow is installed.
$ pipenv install pillow
$ cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
django = "*"
djangorestframework = "*"
django-filter = "*"
djangorestframework-jwt = "*"
pillow = "*"← added
[requires]
python_version = "3.7"
If you are building an environment with pip or pip3,
$ sudo pip install pillow
Or
$ sudo pip3 install pillow
Install with.
Add a model field to store the image in the Coupon class of models.py. If you install pillow, you can use the field type ʻImageField` that handles image files.
The definition is like this. ʻUpload_to =` part is the minimum required.
[Field name] = models.ImageField(upload_to=‘[Relative path to the folder that stores the image files]’)
The starting point of "relative path of the folder that stores the image file" is the path specified in MEDIA_ROOT
defined in settings.py.
As shown below, I added an ImageField with the field name image.
In my case, I got an error when creating the migration file unless I allowed null(null = True)
.
models.py
class Coupon(models.Model):
code = models.CharField(max_length=20)
benefit = models.CharField(max_length=1000)
explanation = models.CharField(max_length=2000)
image = models.ImageField(upload_to='images/', null=True) #add to
store = models.CharField(max_length=1000)
start = models.DateField()
deadline = models.DateField()
status = models.BooleanField()
As mentioned above, in settings.py under the folder of the project name, specify the URL of the starting point when referencing the image file with a relative path in MEDIA_ROOT
.
In my case, I wanted to create a folder to store the image files under the app folder, so I specified the URL of the app folder. Since the project folder is defined by BASE_DIR
, it is described as follows.
It seems that the folder to store the image file is automatically generated when the image is uploaded for the first time, but I did not know it, so I made it myself with mkdir images
.
ami_coupon_api/settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'coupon')
MEDIA_URL
specifies the address that will be the starting point when referencing by URL.
In my case, the address when GETting the Coupon model data is [ip (domain)]: [port] / api / coupons /
, so when referencing the image, [ip (domain)]: [port" ] / api / coupons / images
was set starting from / api / coupons /
.
Project name folder/settings.py
MEDIA_URL = '/api/coupons/'
You need to set in urls.py to refer to the image by URL. Open urls.py under the project name directory and add the following import statement and urlpatterns declaration. It is a setting for handling static files such as images, and it seems that it can be handled almost like a fixed phrase.
ami_coupon_api/urls.py
from django.conf import settings #Added for image reference
from django.contrib.staticfiles.urls import static #Added for image reference
from django.contrib.staticfiles.urls import staticfiles_urlpatterns #Added for image reference
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
If you're using the Django Rest Framework and have set a model field that responds to serializer.py, change the setting to respond to the URL of the image file.
The part of fields =
below. In the case of ’__ all__’
, it is a setting that responds to the values of all model fields, so no change is necessary.
serializer.py
from rest_framework import serializers
from .models import Coupon
class CouponSerializer(serializers.ModelSerializer):
class Meta:
model = Coupon
fields = '__all__'
Since I changed the definition of the model, I will migrate it to reflect the change in the DB.
Create a migration file → Migrate. (If you are using pipenv, run it in the shell of the virtual environment)
$ python manage.py makemigrations [app name]
$ python manage.py migrate
This completes the settings for handling image files, so I used the admin page of django to directly input the image and check if it is actually displayed.
You can update the image by launching the django server, logging in to the django admin page and opening the coupon model page. Directly update the image created for the coupon.
Then use the curl command to get the json of the response to the GET request.
$ curl -X GET http://127.0.0.1:8000/api/coupons/
As shown below, the URL of the image file is included, so copy it and access it with a browser.
[{"id": 1, "code": "0001", "benefit": "1,000 yen discount from payment", "explanation": "Limited to customers using 5,000 yen or more. Cannot be used with other coupons. "," image ":" ** http://127.0.0.1:8000/api/coupons/images/coupon-image-001_GKrT1ju.png ** "," store ":" All stores "," start ":" 2019 -10-01 "," deadline ":" 2019-12-31 "," status ": true}
If the image of the coupon set in the browser is displayed, it is successful.
Recommended Posts