This is a blog project with react.js/next.js frontend, django backend, powered by linux, nginx, gunicorn, redis in docker containers.
Frontend: Next.js (React.js) - server Node.js
Backend: Django (python framework)
Cache system: Redis
Web server: Nginx
WSGI (Web Server Getaway Interface): Gunicorn
Database: postgresql
docker-compose up
docker-compose up -d (runs in background)
access to localhost:5555
access to /api/ or /admin/ => django application
access to everything else => Next.js application
/static/ => specified static folder
/media/ => specified media folder (user uploaded media)
frontend: create a .env.dev file in frontend folder according to .env.sample.
backend: create a .env.dev file in backend folder according to .env.sample.
- add
DJANGO_SETTINGS_MODULE=blog.settingsin your .env file. - Do NOT add "init.py" file under test folder. Otherwise, pytest can't find modules for some reason.
- start pytest
docker container exec -it backend sh -c "pytest"
pytest -v (verbose, show more detail)
- if "backend/countries/fixtures/countries_fixtures.json" doesn't exist, do the following:
docker container exec -it backend sh -c "python countries_data_convert.py"
this will create the countries_fixtures.json file. - load the data from the json file
docker container exec -it backend sh -c "python manage.py loaddata countries/fixtures/countries_fixtures.json"
** load all the initial data at once**docker container exec -it backend sh -c "python3 manage.py loaddata /fixtures/.json"
I created a script to create a super user in one command.
Edit email and password in backend/scripts/add_superuser.py
docker container exec -it backend sh -c "python manage.py runscript add_superuser"
I created a script reset migrations in dev environment.
- drop the database.
- remove all the migration files.
- make new migration files and migrate again.
docker container exec -it backend sh -c "python manage.py runscript reset_migrate"or
docker container exec -it backend sh -c "python cmanage.py resetmigrate"
docker container exec -it backend sh -c "python cmanage.py startapp app_name singular_app_name"
*singular_app_name is optional
This command creates a folder and scripts including default models ...etc like always but also..
basic serializers.py, test file in tests folder, urls.py, add basic model views script in views.py
It also adds the app in the INSTALLED_APPS in the settings.py!!
docker container exec -it backend sh -c "python manage.py runscript add_api --script-args app_name singular_app_name"
*singular_app_name is optional. If it is empty, singular will be app_name without last plural "s" if any.
You should consider caching the result of a request when the following cases are true:
- rendering the page involves a lot of database queries and/or business logic,
- the page is visited frequently by your users,
- the data is the same for every user,
- and the data does not change often.
CACHE_TTL = getattr(settings, 'CACHE_TTL', DEFAULT_TIMEOUT)
@cache_page(CACHE_TTL)
def get_posts():
- Image sliders Example of using Image slider component.
<ImageSliderManager>
<ImageSliderItem image="/images/header/odaiba.jpg">
<h1 className="text-white font-semibold text-5xl">
Pick up Japanese with <b className="text-red-600">Jp</b>launch.
</h1>
<p className="mt-4 text-lg text-gray-300">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Vivamus nec finibus nisl. Mauris quis erat vitae tellus venenatis lobortis.
</p>
</ImageSliderItem>
<ImageSliderItem image="/images/header/fuji.jpg">
<h1 className="text-white font-semibold text-5xl">
Pick up Japanese with <b className="text-red-600">Jp</b>launch.
</h1>
<p className="mt-4 text-lg text-gray-300">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Vivamus nec finibus nisl. Mauris quis erat vitae tellus venenatis lobortis.
</p>
</ImageSliderItem>
<ImageSliderItem image="/images/header/shibuya.jpg">
<h1 className="text-white font-semibold text-5xl">
Pick up Japanese with <b className="text-red-600">Jp</b>launch.
</h1>
<p className="mt-4 text-lg text-gray-300">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Vivamus nec finibus nisl. Mauris quis erat vitae tellus venenatis lobortis.
</p>
</ImageSliderItem>
<ImageSliderItem image="/images/header/osakajo.jpg">
<h1 className="text-white font-semibold text-5xl">
Pick up Japanese with <b className="text-red-600">Jp</b>launch.
</h1>
<p className="mt-4 text-lg text-gray-300">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Vivamus nec finibus nisl. Mauris quis erat vitae tellus venenatis lobortis.
</p>
</ImageSliderItem>
</ImageSliderManager>- Pagination higher order component
this hoc will create pagination functionality in the table.
- pass data to originalData
- pagination hoc will pass paginated data to children component as "data" props.
<Paginator originalData={userData}>
<SelectableTable actionsRequired={true} columns={ADMIN_USER_TABLE_COLUMNS}/>
</Paginator>https://nextjs.org/blog/next-9-2#built-in-css-module-support-for-component-level-styles
css: [component name].module.css
.error {
color: white;
background-color: red;
}
component:
import styles from './Button.module.css'
<button className={styles.error} >click</button>Automated browser testing with cypress.
If you start e2e with cypress for the first time, go to "/blog/frontend" in your host machine
npm install --save-dev cypress cypress-file-upload
In order to start cypress test,
npm test
this will start the new window. select the test js file to execute. test files are in frontend/cypress.
For more info: https://docs.cypress.io/api/api/table-of-contents.html