3

this is my first project with Django and also my first time using Docker. So far I'm really enjoying both of them but I'm facing a problem I couldn't resolve after a week.

I followed this tutorial to build my project : https://medium.com/swlh/setting-up-a-secure-django-project-repository-with-docker-and-django-environ-4af72ce037f0

So far, my project structure looks like like this :

MyProject
├── backend                  # Django "app"
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── permissions.py
│   ├── serializers.py
│   ├── tests.py
│   └── views.py   
│
├── config                  # Django "project"
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py 
│
├── docker                  # Docker configuration files, content close to the source link above
│   └── ... 
│
├── frontend                # independent angular project
│   └── ...        
│
├── __init__.py    <====== # The file responsible of all the trouble !
├── .gitignore   
└── manage.py

My project is up and running fine inside the containers and everything is working as expected. Well, almost everything..

I wrote some simple tests and tried to run them from inside the "web" container (which contains the web app) and whenever i run python manage.py test i get the following errors :

root@web:/code# python manage.py test
System check identified no issues (0 silenced).
EE
======================================================================
ERROR: code.backend (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: code.backend
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/unittest/loader.py", line 470, in _find_test_path
    package = self._get_module_from_name(name)
  File "/usr/local/lib/python3.9/unittest/loader.py", line 377, in _get_module_from_name
    __import__(name)
ModuleNotFoundError: No module named 'code.backend'; 'code' is not a package


======================================================================
ERROR: code.config (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: code.config
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/unittest/loader.py", line 470, in _find_test_path
    package = self._get_module_from_name(name)
  File "/usr/local/lib/python3.9/unittest/loader.py", line 377, in _get_module_from_name
    __import__(name)
ModuleNotFoundError: No module named 'code.config'; 'code' is not a package


----------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (errors=2)
Using selector: EpollSelector

Even with a completely empty tests.py file, I get the above errors.

My understanding of Django and python's project structure is very basic and from what I've found it is related to a bad import which can be fixed by using relative import as described here : Relative imports for the billionth time.

I never manually import code as a package or module, as it is the parent directory of the project inside the web container. Why does the tests tries to import it ? And why only tests are causes this error ?

I guess there is something related to how my project is structured and how my Django settings are defined but i admit that I'm completely lost and a bit desperate as I'm really not familiar with either Django and Docker.

Feel free to ask for any specific file content, and thanks by advance for reading and trying to help !


Edit : as asked below, here is my test file, docker-compose and Dockerfile.

test.py :

from django.test import TestCase
from backend.models import User

class UserTestCase(TestCase) :
    # Setups 
    def create_user(self, email="user@email", username="username", name="name", isActive="true", isSuperUser="false", password="pass"):
        return User.objects.create(email=email, username=username, name=name, isActive=isActive, isSuperUser=isSuperUser, password=password)

    # Models tests
    def test_create_user(self):
        user = self.create_user()
        self.assertIsInstance(user, User)

I should mention that even with an empty test file I get the above errors.


Dockerfile :

# Pull a base image
FROM python:3.9-slim-buster

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Create a working directory for the django project
WORKDIR /django

# Install dependencies
COPY requirements.txt /django/
RUN pip install -r requirements.txt

# Copy the project files into the working directory
COPY . /django/
WORKDIR /code

# Open a port on the container
EXPOSE 8000

docker-compose (removed some irrelevant content) :

version: '3.9'
services:
  db:
    ...
  web:
    build:
      context: ./web
    command: ["./docker/wait-for-it.sh", "db:5432", "--timeout=30", "--strict", "--", "python", "/code/manage.py", "runserver", "0.0.0.0:8000"]
    volumes:
      - ../:/code
    restart: always
    depends_on:
        - db
  front:
    ...

Silver
  • 121
  • 9
  • 1
    can you please post your test file content, the dockerfile, and the docker compose file or even better a link to the Github repo? (I think your on the right track. It might be an issue with the relative import) – Michael Haar Apr 30 '21 at 10:20
  • Hi @MichaelHaar, I'll add the files in an edit. Unfortunately, I won't be able to share the github repo as it's a private project (working on it with other students). – Silver Apr 30 '21 at 10:29

1 Answers1

6

Answering my own question as I have FINALLY found the cause of all my troubles ...

I had created an __init__.py file at the root of my project to define a project version as a constant..

After reading here and there about Django modules and namespaces, I removed the __init__.py from my root directory and that solved the problem.

**edited my question above to show the file in question

Silver
  • 121
  • 9