Django `DetailView`中的对象不可调用错误



我得到了一个object is not callable error,但我不知道为什么。我的模型如下。

class PetDetailView(LoginRequiredMixin, generic.DetailView):
model = Pet
@property
def get_queryset(self):
pet_owner = PetOwner.objects.get(user=self.request.user)
pet = pet_owner.pet_set.get(pk=self.kwargs["pk"])
queryset = pet
return queryset

我做了一些非常类似的事情,用ListView返回不同类中当前用户的宠物列表,当返回pets时,一切都很好。

不过,这是一个DetailView,我只返回一件事。我只想返回当前登录用户的宠物,而不是任何基于主键的宠物。因此,我将重写get_queryset方法,以确保我无权访问与当前登录用户无关的任何其他项目。

我把pet打印到控制台上,得到的是Leo而不是<Pet:Leo>。我认为这可能是个问题,但如果是的话,我不确定为什么在我的python shell中它会像我预期的那样工作。

以防万一这是我的模特。。。

class PetOwner(models.Model):
"""Model representing a pet owner."""
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50, help_text="Enter owner's first name")
last_name = models.CharField(max_length=50, help_text="Enter owner's last name")
email = models.EmailField(
max_length=50, blank=True, null=True, unique=True, help_text="Enter owner's email"
)
phone_number = models.CharField(
max_length=15, blank=True, null=True, unique=True, help_text="Enter owner's phone number"
)
address = models.ForeignKey(
"Address", on_delete=models.SET_NULL, null=True, blank=True
)
class Meta:
"""Controls default ordering of records when querying the Model type."""
ordering = ["first_name", "last_name"]
def __str__(self):
"""String for representing the Model object."""
return self.first_name
def get_absolute_url(self):
"""Returns the url to access a detail record of this pet owner."""
return reverse("petowner_detail", args=[str(self.id)])

class Pet(models.Model):
"""Model representing a pet."""
first_name = models.CharField(max_length=50, help_text="Enter pet's first name")
last_name = models.CharField(max_length=50, help_text="Enter pet's last name")
breeds = models.ManyToManyField("Breed", help_text="Select a breed for this pet")
weight = models.DecimalField(
max_digits=5, decimal_places=2, help_text="Enter pet's weight"
)
date_of_birth = models.DateField(null=True, blank=True)
date_of_death = models.DateField("Died", null=True, blank=True)
owners = models.ManyToManyField(PetOwner, help_text="Select an owner for this pet")
address = models.ForeignKey(
"Address", on_delete=models.SET_NULL, null=True, blank=True
)
class Meta:
"""Controls the default ordering of records when querying the Model type."""
ordering = ["last_name", "first_name"]
def __str__(self):
"""String for representing the Model object."""
return self.first_name
def get_absolute_url(self):
"""Returns the url to access a detail record for this pet."""
return reverse("pet_detail", args=[str(self.id)])
def display_owner(self):
"""Create a string for the PetOwner. This is required to display owner in Admin."""
return ", ".join(owner.first_name for owner in self.owners.all()[:3])
def display_breed(self):
"""Create a string for the Breed. This is required to display breed in Admin."""
return ", ".join(breed.name for breed in self.breeds.all()[:3])
display_owner.short_description = "Parent"

根据Django文档,

get_queryset((:返回将用于检索此视图将显示的对象的查询集。默认情况下,如果设置了queryset属性,get_queryset((将返回该属性的值,否则它将通过调用模型属性的默认管理器上的all((方法来构造queryset。

您使用的是pet_owner.pet_set.get(pk=self.kwargs["pk"])getfilter之间的区别在于filter返回查询集对象,而get返回所需对象。您需要使用filter而不是get来实现此功能。

pet_owner.pet_set.filter(pk=self.kwargs["pk"])如果没有其他问题,这应该有效。

要做到这一点,就这样做。

# remove property decorator and replace second get with filter.
def get_queryset(self):
pet_owner = PetOwner.objects.get(user=self.request.user)
pet = pet_owner.pet_set.filter(pk=self.kwargs["pk"])
queryset = pet
return queryset

错误Pet object is not callable是因为属性decorator,@property decorator在Python中如何工作?

最新更新