![](/img/trans.png)
[英]Django rest-api - attributeerror: 'str' object has no attribute '_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.