繁体   English   中英

psycopg2.errors.UndefinedTable:关系“练习”不存在 - Django 测试

[英]psycopg2.errors.UndefinedTable: relation “exercises” does not exist - Django Testing

我开始在 django 中编写我的第一个测试。 我在测试基于 model 的 POST 方法时遇到问题。

我的项目树看起来:

-   db.sqlite3
-   manage.py
-   tree.txt
-   
----api
-   -   admin.py
-   -   apps.py
-   -   models.py
-   -   serializers.py
-   -   urls.py
-   -   views.py
-   -   __init__.py
-   -   
-   ----migrations
-   -   -   0001_initial.py
-   -   -   __init__.py
-   -   -   
-   -           
-   ----tests
-   -   -   test_models.py
-   -   -   test_urls.py
-   -   -   test_views.py
-   -   -   __init__.py
-   -   -   
-   -           
-           
----drummingpractice
-   -   asgi.py
-   -   settings.py
-   -   urls.py
-   -   wsgi.py
-   -   __init__.py
-   -   
-           
----frontend
-   -   admin.py
-   -   apps.py
-   -   models.py
-   -   urls.py
-   -   views.py
-   -   __init__.py
-   -   
-   ----migrations
-   -   -   __init__.py
-   -   -   
-   -           
-   ----templates
-   -   ----frontend
-   -           exercises_catalog.html
-   -           exercise_add.html
-   -           workouts_history.html
-   -           workouts_stats.html
-   -           workout_add.html
-   -           
-   ----tests
-   -   -   test_models.py
-   -   -   test_urls.py
-   -   -   test_views.py
-   -           
-           
----static

我为应用程序“前端”编写测试。 我试过测试 function 'add_exercises'

前端视图.py

def add_exercise(request):
    if request.method == 'POST':
        data = request.POST
        how_many_img = len(request.FILES.getlist('images'))
        next_exercise_id = Exercises.objects.values('exercise_id').order_by('-exercise_id')[0]['exercise_id'] + 1

        # selected module
        if data['module'] != 'none':
            img_path = '/exercises_img/{module_id}/{exercise_id}/'.format(module_id=data['module'],
                                                                          exercise_id=next_exercise_id)
            module_id = data['module']

        # create new module
        elif data['module_new'] != '':
            Modules.objects.get_or_create(module_name=data['module_new'])   # insert modules...
            new_module_id = Modules.objects.values('module_id').get(module_name=data['module_new'])['module_id']   # get newest module_id
            img_path = '/exercises_img/{module_id}/{exercise_id}/'.format(module_id=new_module_id,
                                                                          exercise_id=next_exercise_id)
            module_id = new_module_id
        else:
            return HttpResponse('Select existing module or create new')

        result = upload_file(request=request, module_id=module_id, exercise_id=next_exercise_id)

        if result:
            # change format dd/mm/YYYY HH:SS -> dd-mm-YYYY HH:SS
            lesson_datetime_normalized = data['lesson_datetime'].replace('/', '-')

            exercise = Exercises.objects.create(
                exercise_name=data['exercise_name'],
                module=Modules.objects.get(module_id=module_id),
                lesson_datetime=lesson_datetime_normalized,
                lesson_tempo=data['lesson_tempo'],
                img_path=img_path,
                note=data['note'],
                how_many_img=how_many_img
            )
            return redirect('catalog')
        else:
            return HttpResponse('Something wrong with upload image')
    elif request.method == 'GET':
        print('jestem w get')
        #modules = Modules.objects.all().order_by('module_id')
        modules = Modules.objects.raw(
        'select * from modules order by module_id asc;')

        context = {'modules': modules}
        return render(request, 'frontend/exercise_add.html', context)

我在前端应用程序中的“test_views.py”文件如下所示:

前端.tests.test_views.py

from django.test import TestCase, Client
from django.urls import reverse

from django.apps import apps
Modules = apps.get_model('api', 'Modules')
Exercises = apps.get_model('api', 'Exercises')
Workouts = apps.get_model('api', 'Workouts')

class TestViews(TestCase):

    def setUp(self):
        self.client = Client()
        self.catalog_url = reverse('catalog')
        self.workouts_url = reverse('workouts')
        self.stats_url = reverse('stats')
        self.add_exercise_url = reverse('exercise-add')

    def test_catalog_GET(self):
        response = self.client.get(self.catalog_url)

        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'frontend/exercises_catalog.html')

    def test_workouts_GET(self):
        response = self.client.get(self.workouts_url)

        self.assertIsNotNone(response.context['workouts'])  # verify if context is not None
        self.assertEqual(response.status_code, 200)         # verify status_code
        self.assertTemplateUsed(response, 'frontend/workouts_history.html')

    def test_stats_GET(self):
        response = self.client.get(self.stats_url)

        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'frontend/workouts_stats.html')

    def test_add_exercise_GET(self):
        response = self.client.get(self.add_exercise_url)
            
        self.assertEqual(response.status_code, 200)                         # undefinedTable 'modules' not exist
        self.assertTemplateUsed(response, 'frontend/exercise_add.html')

    def test_add_exercise_POST(self):

        response = self.client.post(self.add_exercise_url, {
            'exercise_name': 'exercise test 1',
            'module': 1,
            'lesson_datetime': '01-01-2021 10:00',
            'lesson_tempo': 70,
            'img_path': '/exercises_img/test/100/',
            'note': 'notatka testowa',
            'how_many_img': 1
        })

        self.assertEquals(response.status_code, 302) # undefinedTable 'exercises' not exist
        

前 3 个测试运行正常,但 'test_add_exercise_GET' 和 'test_add_exercise_POST' 抛出错误。

Traceback (most recent call last):
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\drummingpractice\frontend\tests\test_views.py", line 69, in test_add_exercise_POST
    'how_many_img': 1
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\test\client.py", line 751, in post
    response = super().post(path, data=data, content_type=content_type, secure=secure, **extra)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\test\client.py", line 408, in post
    secure=secure, **extra)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\test\client.py", line 473, in generic
    return self.request(**r)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\test\client.py", line 719, in request
    self.check_exception(response)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\test\client.py", line 580, in check_exception
    raise exc_value
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\drummingpractice\frontend\views.py", line 32, in add_exercise
    next_exercise_id = Exercises.objects.values('exercise_id').order_by('-exercise_id')[0]['exercise_id'] + 1
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\models\query.py", line 317, in __getitem__
    qs._fetch_all()
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\models\query.py", line 1324, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\models\query.py", line 109, in __iter__
    for row in compiler.results_iter(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size):
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\models\sql\compiler.py", line 1124, in results_iter
    results = self.execute_sql(MULTI, chunked_fetch=chunked_fetch, chunk_size=chunk_size)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\models\sql\compiler.py", line 1169, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\backends\utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\backends\utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\Andrzej\PycharmProjects\DrummingPractice\venv\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: BŁĄD:  relation "exercises" does not exist
LINE 1: SELECT "exercises"."exercise_id" FROM "exercises" ORDER BY "...
                                              ^

我认为问题出在我的模型上,因为我在“前端”应用程序中使用来自“api”的模型。 我使用“makemigrations”和“migrate”尝试了 SO 的解决方案,但我得到“没有检测到更改”。 我还尝试从 api 重置迁移并从 0 生成,但仍然相同。

有人知道出了什么问题吗? 如果具有来自不同应用程序的模型的架构可以吗?

编辑

models.py(API 应用程序)

from django.db import models

class Exercises(models.Model):
    exercise_id = models.AutoField(primary_key=True)
    exercise_name = models.CharField(max_length=500, blank=True, null=True)
    module = models.ForeignKey('Modules', models.DO_NOTHING, blank=True, null=True)
    lesson_datetime = models.DateTimeField(blank=True, null=True)
    lesson_tempo = models.IntegerField(blank=True, null=True)
    img_path = models.CharField(max_length=500, blank=True, null=True)
    note = models.CharField(max_length=500, blank=True, null=True)
    how_many_img = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'exercises'


class Modules(models.Model):
    module_id = models.AutoField(primary_key=True)
    module_name = models.CharField(max_length=500, blank=True, null=True)
    note = models.CharField(max_length=500, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'modules'


class Workouts(models.Model):
    workout_id = models.AutoField(primary_key=True)
    exercise = models.ForeignKey(Exercises, models.DO_NOTHING, blank=True, null=True)
    workout_datetime_start = models.DateTimeField(blank=True, null=True)
    workout_datetime_end = models.DateTimeField(blank=True, null=True)
    workout_tempo = models.IntegerField(blank=True, null=True)
    video_path = models.CharField(max_length=500, blank=True, null=True)
    note = models.CharField(max_length=500, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'workouts'

models.py(前端应用程序)为空

我在 postgresql 中的表是(跳过 django 表):

  • 模块
  • 练习
  • 锻炼

名称正确,小写。

正如我所看到的,有错误的测试是test_add_exercise_POST ,这是因为你在测试环境中从一个空数据库开始,你不能做Exercises.objects.values('exercise_id').order_by('-exercise_id')[0]['exercise_id'] + 1add_exercise function 中,在创建测试练习对象并保存到测试数据库之前。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM