Testing apps.py in django - django

How can I write a test to cover my apps.py files for each model in a django application? I need 100% code coverage and cannot figure out how to test these files. Example of one of my apps.py files:
from django.apps import AppConfig
class ReportsConfig(AppConfig):
name = 'reports'

you could do it like this:
from django.apps import apps
from django.test import TestCase
from reports.apps import ReportsConfig
class ReportsConfigTest(TestCase):
def test_apps(self):
self.assertEqual(ReportsConfig.name, 'reports')
self.assertEqual(apps.get_app_config('reports').name, 'reports')

Related

Django Model Import Error: ValueError: attempted relative import beyond top-level package

I have created a new app "grn" in my django project and tried to import the models from another app named "packsapp" in the same project like this:
Models.py
from ..packsapp.models import *
But I got the following error:
ValueError: attempted relative import beyond top-level package
Here's the structure of the app:
yantra_packs
grn
--migrations
__init__.py
admin.py
apps.py
models.py
tests.py
views.py
media
packsapp
--migrations
templates
templatetags
views1
__init__.py
apps.py
decorators.py
forms.py
models.py
urls.py
views.py
How can I import the models of the packsapp in the grn ??
The root directory of a Django project is not a Python package or module. So relative imports across Django apps will not work. Use an absolute import instead:
from packsapp.models import *

How to override app_settings while testing

Okay now, I have
settings.py
SETTING1='value'
SETTING2='value'
After that we realized that these settings SETTING1 and SETTING2 are more specified to app1
So we've added them apps.py
from django.apps import AppConfig
class EXAPPConfig(AppConfig):
name = 'EXAPPConfig'
verbose_name = "EXAPPConfig"
SETTING1 = 'value'
def ready(self):
pass
and call them withviews.py
app_settings = apps.get_app_config('ex_app')
app_settings.SETTING1
according to Django documentation
So how can I override them with override_settings at tests
#override_settings
I tried #patch to patch the config app but failed
You can mock only an attribute of your app config with this:
from unittest.mock import patch
from django.apps import apps
from django.test import TestCase
class EXAPPTest(TestCase):
def test_mocking_app_config(self):
original = apps.get_app_config('ex_app').SETTING1
with patch.object(apps.get_app_config('ex_app'), 'SETTING1', new='definitely-not-original'):
mocked = apps.get_app_config('ex_app').SETTING1
self.assertNotEqual(original, mocked)

Can I make a folder of forms and views and use an __init__.py file like models and test?

I would like to keep my views and forms separate, just like you can with models. Are you able to make a directory of views and forms, and if so, what goes in the init.py files for each.
Update:
I made my folders, but I keep getting errors. Here's all my code info:
myproject structure (abbreviated):
myproject/
myproject/
name/
forms/
__init__.py
name_form.py
models/
__init__.py
name_model.py
urls.py
views/
__init__.py
name_view.py
models/init.py
from .name_model import Name
models/name_model.py
from django.db import models
from django.urls import reverse
class Name(models.Model):
...
forms/__init__.py and views/__init__.py are blank files.
urls.py
from django.urls import path
from name.views import name_view
app_name = 'name'
urlpatterns = [
path('', views.name_view, name='name-view'),
]
forms/name_form.py
from django.forms import ModelForm, TextInput
from name.models import Name
class NameForm(ModelForm):
class Meta:
model = Name
views/name_view.py
from django.shortcuts import render, redirect
from name.forms import NameForm
def name_view(request):
...
I run python3 manage.py makemigrations in the terminal and get:
/myproject/name/views/name_view.py", line 4, in <module>
from name.forms import NameForm
ImportError: cannot import name 'NameForm'
Thinking you can't make a ModelForm without a model, I run python3 manage.py migrate and get the same error.
I created a project to isolate this issue. Without the folders it worked, unless I messed up my original code trying to get this to work.
Just make a folder for your views and a folder for your forms wherever you want them to be and put an empty __init__.py file into each folder. The purpose of the __init__.py file is to tell python to treat the folder as a module. Then make your views.py file and your forms.py file in their respective directories and now you can do...
from myproject.path.to.views import MyView
from myproject.path.to.forms import MyForm
...as if it were any other module. Which it is.

Django Cookiecutter: How to import AUTH_USER_MODEL in config/settings/base.py?

As we know, Django-Cookiecutter has a different setup for settings files. The regular from django.conf import settings doesn't work here.
I want to reference to the custom user model defined in the base.py file in the settings directory. Any ideas?
Below is my project layout:
repository/
config/
settings/
__init__.py
base.py # where the auth_user_model variable is defined
local.py
production.py
test.py
app_dir/
users/
__init__.py
models.py # where the custom user model is stored
I also tried to import the custom user model directly from users/models.py as below:
from users.models import User
But got the following error:
RuntimeError: Model class users.models.User doesn't declare an
explicit app_label and isn't in an application in INSTALLED_APPS.
Tried the following, and it seems to work so far:
from config.settings.base import AUTH_USER_MODEL
from django.contrib.auth import get_user_model
It'll return django user class that you defined in base.py
Edit:
from django.conf.settings import AUTH_USER_MODEL

Flask Blueprints sharing

I want to make an API with Flask and it also needs to have an admin panel.
I guess that Blueprints are the way to go, but I don't want to make models twice.
My structure is going to be this:
- app
- api
- admin
- models
So my question is: How can I access the models in the models folder in my api blueprint and my admin blueprint?
Thanks in advance.
if you'd in a module within the api or admin folders you can import anything from a module in the models folder using this notation
from ..models.module_name import model1, model2, etc
for small projects i usually keep all the models in a single models.py file like:
[app]
[blueprint_1]
__init__.py
views.py
[blueprint_2]
[static]
[templates]
__init__.py
models.py
then from within any of your blueprint files just:
from ..models import model1, model2, etc
About the import, If your directory include __init__.py then it is a python package so . use for current dir. For example:
auth/
__init__.py
forms.py
views.py
#views.py
from forms import Form name
from . import auth_blueprint # imports from __init__.py
So if you wants to import from another directory you have to use .. to imports from __init__.py file let's say your models directory include those files :
models/
__init__.py
UserModel.py
Now let's import models for auth module :
#auth/views.py
from .. import models # import froms models/__init__.py
from ..models import UserModel