Почему импорт моделей не работает в служебном файле в одном каталоге? - PullRequest
0 голосов
/ 26 июня 2019

Из views.py я вызываю функцию, которая находится в другом файле в том же каталоге (utils.py).ошибки utils.py, поскольку он не может импортировать модели из models.py, который находится в том же каталоге.

Я получаю следующую ошибку:

File "/ home / myuser / site / core/utils.py ", строка 1, в 2019-06-26 15: 22: 46,645: из импорта .models (2019-06-26 15: 22: 46,645: ********************************************************** 2019-06-26 15: 22: 46,646: Есливы видите ошибку импорта и не знаете, почему, 2019-06-26 15: 22: 46 646: у нас есть специальная страница помощи, чтобы помочь вам отладить: 2019-06-26 15: 22: 46 646: https://help.pythonanywhere.com/pages/DebuggingImportError/ 2019-06-26 15: 22: 46,646: *************************************************** 2019-06-26 15: 22: 51 962: Ошибка при запуске приложения WSGI 2019-06-26 15: 22: 51 963: Ошибка импорта: невозможно импортировать имя «Фильм»

utils.py

from .models import(
    Movie,
    Album,
    Book)

def get_weekly_tops():
    start_date, end_date = getThisWeekStartEnd()

    book = Book.objects.filter(release_date__range=[start_date, end_date]).filter(active=True).order_by('-amazon_rating')[:1]
    theater = Movie.objects.filter(release_date__range=[start_date, end_date]).filter(active=True).filter(bluray_date__isnull=True).order_by('-imdb_rating')[:1]
    bluray = Movie.objects.filter(bluray_date__range=[start_date, end_date]).filter(active=True).filter(bluray_date__isnull=False).order_by('-imdb_rating')[:1]
    album = Album.objects.filter(release_date__range=[start_date, end_date]).filter(active=True).order_by('-base_rating')[:1]

    if len(book) == 0:
        book = Book.objects.filter(release_date__range=[start_date + timedelta(days=-6), end_date + timedelta(days=-6)]).filter(active=True).order_by('-amazon_rating')[:1]

    if len(theater) == 0:
        theater = Movie.objects.filter(release_date__range=[start_date + timedelta(days=-6), end_date + timedelta(days=-6)]).filter(active=True).filter(bluray_date__isnull=True).order_by('-imdb_rating')[:1]

    if len(bluray) == 0:
        bluray = Movie.objects.filter(bluray_date__range=[start_date + timedelta(days=-6), end_date + timedelta(days=-6)]).filter(active=True).filter(bluray_date__isnull=False).order_by('-imdb_rating')[:1]

    if len(album) == 0:
        album = Album.objects.filter(release_date__range=[start_date + timedelta(days=-6), end_date + timedelta(days=-6)]).filter(active=True).order_by('-base_rating')[:1]

    return {'book':book, 'theater':theater, 'bluray':bluray, 'album':album}

views.py

from .utils import(
    get_weekly_tops)

def index(request):
    weekly_tops = get_weekly_tops()

    return render(
        request,
        'index.html',
        context={
            'weekly_tops':weekly_tops
        },
    )

models.py

from django.db import models
from django.urls import reverse
from django.db.models.signals import pre_save, post_save
from .utils import unique_slug_generator, id_generator, curated_slug_generator, poll_slug_generator
from django.contrib.auth.models import User
from django.dispatch import receiver
from datetime import datetime
from django_countries.fields import CountryField

class Movie(models.Model):
    """
    Movie class
    """

    # Fields
    tmdb_id = models.IntegerField()
    title = models.CharField(max_length=100, help_text="Enter title")
    release_date = models.DateField()
    bluray_date = models.DateField(null=True, blank=True)
    poster = models.CharField(max_length=200, help_text="Enter poster file")
    overview = models.TextField(help_text="Enter overview")
    genre = models.ManyToManyField(MovieGenre, help_text="Select a genre for this movie")
    mpaa_rating = models.CharField(max_length=10, help_text="MPAA Rating") #details call
    run_time = models.IntegerField()
    slug = models.SlugField(max_length=100, null=True, blank=True)
    imdb_rating = models.IntegerField(default=60)
    trailer = models.CharField(max_length=100, help_text="Enter trailer link")
    director = models.CharField(max_length=100, blank=True, help_text="Enter director")
    theater_link = models.CharField(max_length=255, null=True, blank=True, help_text="Enter theater link")
    bluray_link = models.CharField(max_length=255, null=True, blank=True, help_text="Enter blu-ray link")
    votes = models.IntegerField(default=0)
    num_ratings = models.IntegerField(default=0)
    running_total = models.IntegerField(default=0)
    weighted_rating = models.IntegerField(default=0)
    active = models.BooleanField(default=False)
    flashback = models.BooleanField(default=False)
    processed = models.BooleanField(default=False)

    # Metadata
    class Meta:
        ordering = ["release_date", "title"]

    # Methods
    def get_absolute_url(self):
        """
        Returns the url to access a particular instance of Movie.
        """
        return reverse('movie-detail', kwargs={'slug': self.slug})

    @property
    def movie_length(self):
        "Returns the movie's length in hours:minutes."
        if self.run_time == 0:
            return None
        else:
            hours = int(self.run_time / 60)
            minutes_in_hrs = hours * 60
            minutes = self.run_time - minutes_in_hrs
            return '%d:%s' % (hours, str(minutes).zfill(2))

    @property
    def format_type(self):
        "Returns the movie's type based on length."
        if not self.run_time:
            return None
        elif self.run_time <= 24:
            return "Short"
        elif self.run_time <= 40:
            return "Featurette"
        else:
            return "Feature"

    @property
    def rating_percent(self):
        if self.imdb_rating == 0:
            return None
        else:
            return str(self.imdb_rating)+"%"

    @property
    def weighted_percent(self):
        if self.weighted_rating == 0:
            return None
        else:
            return str(self.weighted_rating)+"%"

    @property
    def length_interval(self):
        "Returns the movie's length as an interval."
        if self.run_time == 0:
            return None
        else:
            hours = int(self.run_time / 60)
            minutes_in_hrs = hours * 60
            minutes = self.run_time - minutes_in_hrs
            return 'PT%dH%dM' % (hours, minutes)

    def __str__(self):
        """
        String for representing the Movie object (in Admin site etc.)
        """
        return self.title

class Album(models.Model):
    """
    Album class
    """

    # Fields
    spotify_id = models.CharField(max_length=50)
    artist = models.CharField(max_length=100, help_text="Enter artist")
    title = models.CharField(max_length=100, help_text="Enter title")
    image = models.CharField(max_length=100, help_text="Enter image file")
    big_image = models.CharField(max_length=100, help_text="Enter image file")
    release_date = models.DateField()
    record_type = models.CharField(max_length=25, help_text="Enter record type")
    slug = models.SlugField(max_length=100, null=True, blank=True)
    length = models.IntegerField() #in seconds
    link = models.CharField(max_length=255, blank=True, help_text="Enter purchase link")
    genre = models.ManyToManyField(AlbumGenre, blank=True, help_text="Select a genre for this album")
    base_rating = models.IntegerField(default=60)
    votes = models.IntegerField(default=0)
    num_ratings = models.IntegerField(default=0)
    running_total = models.IntegerField(default=0)
    weighted_rating = models.IntegerField(default=0)
    active = models.BooleanField(default=False)
    flashback = models.BooleanField(default=False)
    processed = models.BooleanField(default=False)

    # Metadata
    class Meta:
        ordering = ["release_date", "artist", "title"]

    # Methods
    def get_absolute_url(self):
        """
        Returns the url to access a particular instance of Album.
        """
        return reverse('album-detail', kwargs={'slug': self.slug})

    def __str__(self):
        """
        String for representing the Album object (in Admin site etc.)
        """
        return self.title

    @property
    def rating_percent(self):
        if self.base_rating == 0:
            return None
        else:
            return str(self.base_rating)+"%"

    @property
    def weighted_percent(self):
        if self.weighted_rating == 0:
            return None
        else:
            return str(self.weighted_rating)+"%"

    @property
    def album_length(self):
        "Returns the album's length in minutes:seconds."
        if self.length == 0:
            return None
        else:
            minutes = int(self.length / 60)
            secs_in_mins = minutes * 60
            seconds = self.length - secs_in_mins
            return '%d:%s' % (minutes, str(seconds).zfill(2))

    @property
    def length_interval(self):
        "Returns the album's length as an interval."
        if self.length == 0:
            return None
        else:
            minutes = int(self.length / 60)
            secs_in_mins = minutes * 60
            seconds = self.length - secs_in_mins
            return 'PT%dM%dS' % (minutes, seconds)

class Track(models.Model):
    """
    Track class
    """

    # Fields
    spotify_id = models.CharField(max_length=50)
    title = models.CharField(max_length=100, help_text="Enter title")
    length = models.IntegerField() #in seconds
    track_num = models.IntegerField()
    album = models.ForeignKey(Album, on_delete=models.CASCADE)
    preview = models.CharField(max_length=200, blank=True, help_text="Enter preview url")

    # Metadata
    class Meta:
        ordering = ["album", "track_num"]

    def __str__(self):
        """
        String for representing the Track object (in Admin site etc.)
        """
        return self.title

    @property
    def track_length(self):
        "Returns the track's length in minutes:seconds."
        minutes = int(self.length / 60)
        secs_in_mins = minutes * 60
        seconds = self.length - secs_in_mins
        return '%d:%s' % (minutes, str(seconds).zfill(2))

    @property
    def length_interval(self):
        "Returns the track's length as an interval."
        minutes = int(self.length / 60)
        secs_in_mins = minutes * 60
        seconds = self.length - secs_in_mins
        return 'PT%dM%dS' % (minutes, seconds)

class Book(models.Model):
    """
    Book class
    """

    # Fields
    title = models.CharField(max_length=150, help_text="Enter title")
    cover_image = models.CharField(max_length=200, help_text="Enter image file")
    description = models.TextField(help_text="Enter description")
    author = models.CharField(max_length=100, help_text="Enter author")
    pages = models.IntegerField()
    release_date = models.DateField()
    genre = models.ManyToManyField(BookGenre, help_text="Select a genre for this book")
    slug = models.SlugField(max_length=100, null=True, blank=True)
    amazon_rating = models.IntegerField(default=60)
    votes = models.IntegerField(default=0)
    link = models.CharField(max_length=255, blank=True, help_text="Enter purchase link")
    num_ratings = models.IntegerField(default=0)
    running_total = models.IntegerField(default=0)
    weighted_rating = models.IntegerField(default=0)
    active = models.BooleanField(default=False)
    flashback = models.BooleanField(default=False)
    processed = models.BooleanField(default=False)

    # Metadata
    class Meta:
        ordering = ["author", "title"]

    # Methods
    def get_absolute_url(self):
        """
        Returns the url to access a particular instance of Book.
        """
        return reverse('book-detail', kwargs={'slug': self.slug})

    def __str__(self):
        """
        String for representing the Book object (in Admin site etc.)
        """
        return self.title

    @property
    def rating_percent(self):
        if self.amazon_rating == 0:
            return None
        else:
            return str(self.amazon_rating)+"%"

    @property
    def weighted_percent(self):
        if self.weighted_rating == 0:
            return None
        else:
            return str(self.weighted_rating)+"%"

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Ваша проблема - круговой импорт между models.py и utils.py. Что происходит:

  1. utils.py импорт Movie из models.py
  2. models.py импортирует utils.py до определения класса Movie.
  3. utils.py, следовательно, не может импортировать Movie из models, поскольку utils импортируется из models до Movie.

С точки зрения исправления вы можете:

  1. Перестройте utils.py, чтобы все, что требуется models.py, было разделено на другой модуль.

  2. Импортировать методы utils.py из любой функции, в которой они используются.

например.,

def foo():
    from .utils import unique_slug_generator 

    slug = unique_slug_generator()
0 голосов
/ 26 июня 2019

Я думаю, проблема в том, что вы запускаете код вместо вызова

python manage.py runserver

Когда вы запускаете код, импорт из других файлов не работает. Я не уверен, почему, хотя? Просто запустите сервер вместо файла python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...