質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.36%

djangoのrunserverで"The included URLconf 'app.urls' does not appear to have any patterns in it. "が出る

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 719

score 21

runserverしたい

djangoでrunserverしたいのですが、以下のエラーメッセージでrunserverできません。

エラー全文

$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/urls/resolvers.py", line 600, in url_patterns
    iter(patterns)
TypeError: 'module' object is not iterable

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/core/management/commands/runserver.py", line 118, in inner_run
    self.check(display_num_errors=True)
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/core/management/base.py", line 419, in check
    all_issues = checks.run_checks(
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/core/checks/registry.py", line 76, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/core/checks/urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/core/checks/urls.py", line 23, in check_resolver
    return check_method()
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/urls/resolvers.py", line 412, in check
    for pattern in self.url_patterns:
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/****/Python/myVacation/venv/lib/python3.8/site-packages/django/urls/resolvers.py", line 607, in url_patterns
    raise ImproperlyConfigured(msg.format(name=self.urlconf_name)) from e
django.core.exceptions.ImproperlyConfigured: The included URLconf 'app.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.

環境

macOS : 10.15.4
python : 3.8.1
django : 3.2.5

実際のコード

プロジェクト名:app
アプリケーション名;my_vacation, users

# app.urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('my_vacation.urls')),
]
# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'my_vacation',
    'users',
]

ROOT_URLCONF = 'app.urls'
# my_vacation.urls.py
from django.urls import path
from . import views

app_name= 'my_vacation'
urlpatterns = [
    path('', views.VacationList.as_view(), name='index'),
    path('my-vacation/<int:pk>/', views.MyVacation.as_view(), name='my_vacation'),
    path('detail/<int:pk>/', views.VacationDetail.as_view(), name='detail'),
    path('edit/<int:pk>/', views.EditVacation.as_view(), name='edit'),
    path('create/<int:pk>/', views.CreateVacation.as_view(), name='create'),
    path('delete/<int:pk>/', views.DeleteVacation.as_view(), name='delete'),
    path('duplicate/<int:pk>/', views.DuplicateVacation.as_view(), name='duplicate'),
]
# my_vacation.models.py
from django.db import models
from django.contrib.auth.models import AbstractUser

from users.models import User


class Genre(models.Model):
    name = models.CharField(max_length=200)

    def __str__(self):
        return self.name

class MinnanoVacation(models.Model):
    WITH_LIST = (
        ('0', 'ひとりで'),
        ('1', '恋人と'),
        ('2', '友達と'),
        ('3', '家族と'),
        ('4', '見知らぬ誰かと'),
    )

    TIME_REQUIRED_LIST = (
        ('0', '1時間以内'),
        ('1', '2~3時間'),
        ('2', '半日'),
        ('3', '1日'),
        ('4', '1伯以上'),
    )

    title = models.CharField('やりたいこと', max_length=200)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    with_who = models.CharField('誰と', max_length=30, choices=WITH_LIST)
    cost = models.IntegerField('およその金額')
    time_required = models.CharField('所要時間', max_length=30, choices=TIME_REQUIRED_LIST)
    genre = models.ManyToManyField(Genre)
    published = models.BooleanField('公開', default=False)
    yaritai = models.IntegerField('やってみたい', default=0)
    copied = models.IntegerField('コピーされた数', default=0)
    original_id = models.IntegerField(blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
# my_vacation.views.py
from django.shortcuts import render
from django.urls import reverse, reverse_lazy
from django.views.generic import ListView, DetailView, UpdateView, CreateView
from django.db.models import Q

from .models import MinnanoVacation
from .forms import MinnanoVacationForm

class VacationList(ListView):
    model = MinnanoVacation
    template_name = 'index.html'
    context_object_name = 'vacations'
    paginate_by = 10

    def get_queryset(self):
        title = self.request.Get.get('title')
        with_who = self.request.Get.get('with_who')
        cost = self.request.Get.get('cost')
        time_required = self.request.Get.get('time_required')
        genre = self.request.Get.get('genre')

        queryset = MinnanoVacation.objects.order_by('-created_at')

        if title:
            queryset = queryset.objects.filter(
                Q(title__icontains=title)
            )
        elif with_who:
            queryset = queryset.objects.filter(
                Q(with_who__icontains=with_who)
            )
        elif cost:
            queryset = queryset.objects.filter(
                Q(cost__lte=cost)
            )
        elif time_required:
            queryset = queryset.objects.filter(
                Q(time_required__icontains=time_required)
            )
        elif genre:
            queryset = queryset.objects.filter(
                Q(genre__icontains=genre)
            )

        return queryset

    def post(self, request, *args, **kwargs):
        yaritai_id = self.request.POST.get('yaritai')
        vacation = MinnanoVacation.objects.get(id=yaritai_id)
        vacation.yaritai += 1
        vacation.save()
        return reverse('my_vacation:index')


class MyVacation(ListView):
    model = MinnanoVacation
    context_object_name = 'my_vacations'
    template_name = 'my-vacation.html'
    paginate_by = 10

    def get_queryset(self):
        user = get_object_or_404(MinnanoVacation, user.id==self.kwargs['pk'])
        queryset = super().get_queryset().filter(user=user)
        return queryset

class VacationDetail(DetailView):
    template_name = 'detail.html'
    model = MinnanoVacation
    context_object_name = 'vacation'

    def post(self, request, *args, **kwargs):
        yaritai_id = self.request.POST.get('yaritai')
        vacation = MinnanoVacation.objects.get(id=yaritai_id)
        vacation.yaritai += 1
        vacation.save()
        return reverse('my_vacation:detail')



class EditVacation(UpdateView):
    template_name = 'edit.html'
    model = MinnanoVacation
    form_class = MinnanoVacationForm
    # success_url = reverse('my_vacation:index') # <=こいつが原因
    success_url = reverse_lazy('my_vacation:index')


# 文字数制限のため省略
# manage.py
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    """Run administrative tasks."""
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()
$ find . -type d \( -name __pycache__ -o -name migrations -o -name .git \) -prune -false -o -type f

./app/asgi.py
./app/__init__.py
./app/settings.py
./app/urls.py
./app/wsgi.py
./db.sqlite3
./my_vacation/models.py
./my_vacation/__init__.py
./my_vacation/apps.py
./my_vacation/forms.py
./my_vacation/admin.py
./my_vacation/tests.py
./my_vacation/urls.py
./my_vacation/views.py
./users/models.py
./users/__init__.py
./users/apps.py
./users/admin.py
./users/tests.py
./users/views.py
./templates/duplicate.html
./templates/index.html
./templates/my-vacation.html
./templates/create.html
./templates/edit.html
./templates/detail.html
./templates/delete.html
./manage.py

調べたこと

app.urls.pyの記述ミスでこのエラーが出るみたいなのですが、
どこがおかしいのかがわかりません。

足りない情報等あれば追記いたします。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • likelive.geo

    2021/07/22 14:29

    ご確認ありがとうございます。
    エラーを全文記載いたしました。
    よろしくお願いいたします。

    キャンセル

  • dameo

    2021/07/22 16:19

    ありがとうございます。
    スタックトレースを見て、中を見てみたのですが、./app/urls.pyで定義されるurlpatternsが、moduleオブジェクトであれば同じ現象を発生できます。例えば以下のようなコードです。

    import sys
    urlpatterns = sys.modules[__name__]

    circular importな記述もしてみたりしてみましたが、エラーやスタックトレースの出方が違います。
    includeなどの引数が正しくない状況なども試しましたが、The included URLconf 'xxx' のxxx部分がapp.urlsになりませんし、ネストした読み込みなので、スタックが深くなって出方が変わります。従って、./app/urls.pyの内容が質問文のとおりだとすると、このエラーとスタックトレースにはならないという結論に至りました。

    お手数ですが再度./app/urls.pyの内容をご確認ください。
    再確認後も質問文のとおりである場合は、私の方で再現できる完全なコードがない限り、申し訳ありませんが調べられることはありません。

    キャンセル

  • likelive.geo

    2021/07/22 16:53

    あれこれコメントアウトして調べたところ、views.pyのEditVacationでreverse_lazyではなく、reverseを使用していたことが原因でした。
    お時間をかけて調べていただいてありがとうございました。

    キャンセル

回答 1

check解決した方法

+1

reverse => reverse_lazy で解決

views.pyのEditVacationクラスに問題がありました。

success_url = reverse('my_vacation:index') # 誤
success_url = reverse_lazy('my_vacation:index') # 正


クラス変数を設定する段階では、まだurls.pyを読み込んでいないためエラーが出たようです。
reverse_lazyは遅延評価ができるので、この時点でurls.pyが読み込まれてなくても問題なく動作可能。

ただ、同様のケースならImproperlyConfiguredというエラーが出るそうなのですが、なぜ今回のエラーが出たのかはわかりませんでした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/07/22 23:01

    実際には./app/urls.pyは読み込まれており、初期化処理をメインスレッド(main関数を実行してるスレッド)内で行っているようです。ただ正にurlpatternsを設定する最中、include()でimportされた./my_vacation/urls.pyが./my_vacation/views.pyを読み込み、その初期化の際、当該クラス変数の初期化が走ってreverse()によりurlpatternsが設定前に参照されてしまい(ある意味循環参照)、例外が上がり初期化失敗したということのようです。
    上がった例外は報告されず、メインスレッドから起動した別スレッド(django-main-thread)が後から別途urlpatternをチェックをすることで、再度例外が上がり、これが報告されています(質問文含め、いずれのケースでも例外はImproperlyConfiguredになっています)。

    上のコメントではincludeによりimportされたモジュールの例外で初期化されないケースと、reverseによる循環の考慮が足りなかったと反省しております。
    何はともあれ解決してよかったです。

    キャンセル

  • 2021/07/23 06:29 編集

    一応後から読む人のために現象を再現するための簡単な環境構築スクリプトを作ってみました。
    teratailではコメントの空白制御ができないので、base64エンコードさせています。
    以下を実行して出力されるテキストがスクリプトになります。

    base64 --decode <<EOF | gzip -dc
    H4sICOLp+WAAA2NyZWF0ZV9lbnYuc2gAdZNfb9owFMWfdz/FEZpEUeL8gTDBVib2sGmTpnaa1oep
    6oOJHXCV2FEw2fj2sxOgwFRLSa6Pb67v78RRBXJTVVwLsBb13m6MnuBjLGQb611ZfoDdSE1vfvz+
    9fX+bnFIIFlu5ZVIhaK3vQJWoZW6hbso8vd4pXTMc6tabiXVqobSW8vLEuwBbnohiWeu14b6B+Oi
    UhpupbF1Y55lblHtt8qVycUx6juAw+BrGdX7Pp3XtUtwd6q5zTdgdYrb28/3X0ioogBja2XB4y4l
    3jXl1r+5upyTln9QqFKiMkIiTZJ3WUZKC/kXST+iaDbOxCybEWMMJ+coCIL/qi2XYEmYIEjDCZZL
    CorGVAfgyCdBVbVpLBrZysZ5HByCmyHXe80rORxR4BIdkZWN3i4en65pvCMXOOfCofVsOh2nySyK
    JqvpPM3mRzBPcF3jBHIhepI0C2cOJQvnjgXfdF7uhNJrcG3cqWnw8PN7bnRB8GMc4ZMQ4F6FNTiD
    eA+4cHMzXJVmHQ9DdxJ8KdkLnS/D0YgwGAwI54656rZRq6Np3VEh9pqnfo/XHferp52JzvvDAo89
    RN9mt4/vswsi70tXahRS8JLVf/lzmk454oSEJ+oOozz9GP8AfWhQRY4DAAA=
    EOF

    shellでこれを実行してから、
    $ . env/bin/activate
    でvenv環境に入って、
    $ cd mysite
    $ python manage.py runserver
    とすると、現象が発生します。

    mysite/myapp/urls.pyのreverseをreverse_lazyにすると現象が発生しなくなります(importも変える)。

    キャンセル

  • 2021/07/23 08:44

    非常にわかりやすい補足ありがとうございます。
    今回のもちゃんとImproperlyConfiguredの例外でしたね。確認不足でした。

    現象の再現も確認できました。
    ご丁寧にいろいろと教えていただきありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る