簡體   English   中英

'opts = self.remote_field.model._meta' 'AttributeError: 'str' 對象沒有屬性 '_meta''

[英]'opts = self.remote_field.model._meta' 'AttributeError: 'str' object has no attribute '_meta''

我對 django 有點陌生,我正在嘗試構建一個 airbnb 克隆來更好地理解 django。 當我嘗試啟動我的服務器時,我不斷收到錯誤消息。 我對如何解決錯誤感到困惑。 它追溯到我的虛擬環境文件,但我從未直接向其中寫入任何代碼。 我發現如果我刪除 admin.py 文件和 models.py 文件的內容,它會消除錯誤,並且我的服務器會啟動。 我認為這表明錯誤可能來自這些文件之一。 這是錯誤代碼:

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/core/management/commands/runserver.py", line 118, in inner_run
    self.check(display_num_errors=True)
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/core/management/base.py", line 419, in check
    all_issues = checks.run_checks(
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/core/checks/registry.py", line 76, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/checks.py", line 54, in check_admin_app
    errors.extend(site.check(app_configs))
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/sites.py", line 92, in check
    errors.extend(modeladmin.check())
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/options.py", line 122, in check
    return self.checks_class().check(self, **kwargs)
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/checks.py", line 648, in check
    *self._check_list_filter(admin_obj),
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/checks.py", line 804, in _check_list_filter
    return list(chain.from_iterable(
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/checks.py", line 805, in <genexpr>
    self._check_list_filter_item(obj, item, "list_filter[%d]" % index)
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/checks.py", line 848, in _check_list_filter_item
    get_fields_from_path(obj.model, field)
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/utils.py", line 487, in get_fields_from_path
    parent = get_model_from_relation(fields[-1])
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/utils.py", line 438, in get_model_from_relation
    return field.get_path_info()[-1].to_opts.model
  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/db/models/fields/related.py", line 712, in get_path_info
    opts = self.remote_field.model._meta
AttributeError: 'str' object has no attribute '_meta'

這是我的 related.py 文件中突出顯示的行:

opts = self.remote_field.model._meta

這是整個功能:

def get_path_info(self, filtered_relation=None):
        """Get path from this field to the related model."""
        opts = self.remote_field.model._meta
        from_opts = self.model._meta
        return [PathInfo(
            from_opts=from_opts,
            to_opts=opts,
            target_fields=self.foreign_related_fields,
            join_field=self,
            m2m=False,
            direct=True,
            filtered_relation=filtered_relation,
        )]

這是我的 admin.py 文件:

from django.contrib import admin

# Register your models here.
#New
from django.contrib import admin
from django.utils.html import mark_safe
from .models import Room, RoomType, Amenity, Facility, HouseRule, Photo


@admin.register(RoomType, Amenity, Facility, HouseRule)
class ItemAdmin(admin.ModelAdmin):
    """Register model classes inherited from the AbstractItem model"""

    list_display = ("name", "used_by")

    def used_by(self, obj):
        return obj.rooms.count()


@admin.register(Photo)
class PhotoAdmin(admin.ModelAdmin):
    """Register Photo model at admin panel"""

    list_display = ("__str__", "get_thumbnail")

    def get_thumbnail(self, obj):
        return mark_safe(f'<img width="50px" src="{obj.file.url}" />')

    get_thumbnail.short_description = "Thumbnail"


class PhotoInlineAdmin(admin.TabularInline):
    """Photo model's inline admin"""

    model = Photo


@admin.register(Room)
class RoomAdmin(admin.ModelAdmin):
    """Register Room model at admin panel

    Filter by:
        instant_book      : BooleanField
        host.is_superhost : BooleanField
        city              : CharField
        room_type         : RoomType Model
        amenities         : Amenity Model
        facilities        : Facility Model
        house_rules       : HouseRule Model
        country           : CharField

    Search by:
        city              : exact
        host.username     : startwith

    Admin function :
        count_amenities   : return amenities count
        count_facilities  : return facilities count
        count_house_rules : return house_rules count
    """

    inlines = (PhotoInlineAdmin,)

    fieldsets = (
        (
            "Basic Info",
            {"fields": ("name", "description", "country", "address", "price")},
        ),
        ("Times", {"fields": ("check_in", "check_out", "instant_book")}),
        ("Spaces", {"fields": ("guests", "beds", "bedrooms", "baths")}),
        (
            "More About the Space",
            {
                "classes": ("collapse",),
                "fields": ("amenities", "facilities", "house_rules"),
            },
        ),
        ("Last Details", {"fields": ("host",)}),
    )

    raw_id_fields = ("host",)

    list_display = (
        "name",
        "country",
        "city",
        "price",
        "address",
        "guests",
        "beds",
        "bedrooms",
        "baths",
        "check_in",
        "check_out",
        "instant_book",
        "count_amenities",
        "count_photos",
        "total_rating",
    )
    list_filter = (
        "instant_book",
        "host__is_superhost",
        "city",
        "room_type",
        "amenities",
        "facilities",
        "house_rules",
        "country",
    )
    filter_horizontal = ("amenities", "facilities", "house_rules")
    search_fields = ("=city", "^host__username")

    def count_amenities(self, obj):
        return obj.amenities.count()

    def count_photos(self, obj):
        return obj.photos.count()

    count_photos.short_description = "Photo Count"


這是我的 models.py 文件:

from django.db import models

# Create your models here.
#New
from django.urls import reverse
from django_countries.fields import CountryField
from core.models import AbstractTimeStamp


class AbstractItem(AbstractTimeStamp):
    """Abstract Item Model

    Inherit:
        AbstractTimeStamp

    Fields:
        name       : CharField
        created_at : DateTimeField
        updated_at : DateTimeField

    Method:
        __str__ : return name
    """

    name = models.CharField(max_length=80, unique=True)

    class Meta:
        abstract = True

    def __str__(self):
        return self.name


class RoomType(AbstractItem):
    """RoomType Model

    Inherit:
        AbstractItem
    """

    class Meta:
        verbose_name = "Room Type"


class Amenity(AbstractItem):
    """Amenity Model

    Inherit:
        AbstractItem
    """

    class Meta:
        verbose_name_plural = "Amenities"


class Facility(AbstractItem):
    """Facility Model

    Inherit:
        AbstractItem
    """

    class Meta:
        verbose_name_plural = "Facilities"


class HouseRule(AbstractItem):
    """HouseRule Model

    Inherit:
        AbstractItem
    """

    class Meta:
        verbose_name = "House Rule"


class Photo(AbstractTimeStamp):
    """Photo Model

    Inherit:
        AbstractTimeStamp

    Fields:
        caption    : CharField
        file       : ImageField
        room       : Room Model (1:N)
        created_at : DateTimeField
        updated_at : DateTimeField

    Method:
        __str__ : return caption
    """

    caption = models.CharField(max_length=80)
    file = models.ImageField(upload_to="room_photos")
    room = models.ForeignKey("Room", related_name="photos", on_delete=models.CASCADE)

    def __str__(self):
        return self.caption


class Room(AbstractTimeStamp):
    """Room Model

    Inherit:
        AbstractTimeStamp

    Fields:
        name         : CharField
        description  : TextField
        country      : CountryField
        city         : CharField
        price        : IntegerField
        address      : CharField
        guests       : IntegerField
        beds         : IntegerField
        bedrooms     : IntegerField
        baths        : IntegerField
        check_in     : TimeField
        check_out    : TimeField
        instant_book : BooleanField
        host         : users app User model (1:N)
        room_type    : RoomType model (1:N)
        amenities    : Amenity model (N:N)
        facilities   : Facility model (N:N)
        house_rules  : HouseRule model(N:N)
        created_at   : DateTimeField
        updated_at   : DateTimeField

    Method:
        __str__      : return name
        save         : change capitalized city name and save
        total_rating : return all reviews rating avg
        first_photo  : return room's first photo file url
    """

    name = models.CharField(max_length=140)
    description = models.TextField()
    country = CountryField()
    city = models.CharField(max_length=80)
    price = models.IntegerField()
    address = models.CharField(max_length=140)
    guests = models.IntegerField()
    beds = models.IntegerField()
    bedrooms = models.IntegerField()
    baths = models.IntegerField()
    check_in = models.TimeField()
    check_out = models.TimeField()
    instant_book = models.BooleanField(default=False)
    host = models.ForeignKey(
        "users.User", related_name="rooms", on_delete=models.CASCADE
    )
    room_type = models.ForeignKey(
        "RoomType", related_name="rooms", on_delete=models.SET_NULL, null=True
    )
    amenities = models.ManyToManyField("Amenity", related_name="rooms", blank=True)
    facilities = models.ManyToManyField("Facility", related_name="rooms", blank=True)
    house_rules = models.ManyToManyField("HouseRule", related_name="rooms", blank=True)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.city = str.capitalize(self.city)
        super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse("rooms:detail", kwargs={"pk": self.pk})

    def total_rating(self):
        all_reviews = self.reviews.all()

        if len(all_reviews) == 0:
            return 0

        all_ratings = 0

        for review in all_reviews:
            all_ratings += review.rating_average()

        return round(all_ratings / len(all_reviews), 2)

    def first_photo(self):
        try:
            (photo,) = self.photos.all()[:1]
            return photo.file.url
        except Exception:
            return None

    def get_next_four_photos(self):
        photos = self.photos.all()[1:5]
        return photos

我不確定從哪里開始,而且我太害怕直接在虛擬環境中寫入任何內容。 有沒有人知道從哪里開始尋找,或者可能是什么問題?

就在棧中報錯之前,可以看到這部分;

  File "/Users/AUTH_SYSTEM/backend/venv/lib/python3.9/site-packages/django/contrib/admin/checks.py", line 848, in _check_list_filter_item
    get_fields_from_path(obj.model, field)

這是 django 所做的檢查的一部分,它告訴我們它正在查看您的管理類中的list_filter項目。

我會調試這個,通過編輯這個 django 代碼來臨時添加一個打印。 在它執行get_fields_from_path(obj.model, field)之前是這樣的;

print(f"{obj.model}, {field}")

這將顯示在導致錯誤之前要運行的最后一個模型和字段。


上一個答案

所以self.remote_field.model是一個代表模型的字符串值。

您可以通過使用模型的字符串表示來訪問您的模型;

from django.apps import apps

Site = apps.get_model('sites.Site')

因此,如果您有self.remote_field.model的字符串值,那么您應該可以這樣做;

MyModel = apps.get_model(self.remote_field.model)

opts = MyModel._meta

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM