我想写一个查询,当一个艺术家id被搜索,艺术家的信息和他们所有的作品是结果,基本上是Artist
和ArtistPiece
之间的连接查询
#models.py
class Artist(models.Model):
name = models.CharField(max_length=100)
artist = models.CharField(max_length=150)
created_by = models.ForeignKey(User)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class ArtistPiece(models.Model):
artist = models.ForeignKey(Artist, on_delete = models.CASCADE)
piece_name = models.CharField(max_length=50)
details = models.CharField(max_length=100)
#views.py
from .models import Artist, ArtistPiece
class EditArtistViewSet(viewsets.ViewSet):
def edit(self,request,artist_id):
artist = Artist.objects.select_related().get(pk=artist_id)
data = model_to_dict(artist)
return render(
request, 'ArtistInfo/edit.html', {
'editing': 'true',
'edit_data': json.dumps(data),
})
def submit_edit(self,request):
return render(request, 'ArtistInfo/edit.html')
上面的工作,但它没有从ArtistPiece模型中选择任何数据,尽管有主键。然后,在阅读了这篇关于使用select_related
的文章后,我意识到,与其查找艺术家,我必须通过foreign_key查找ArtistPiece,并使用select_related来查找有关艺术家的信息。
I then try this
def edit(self, request, artist_id):
artist = ArtistPiece.objects.get()
data = model_to_dict(artist)
导致以下错误get()
返回多个ArtistPiece——它返回5!搜索后,我发现了这篇文章,上面说我需要使用过滤器而不是get。然后我尝试了这个
def edit(self, request, artist_id):
artist = ArtistPiece.objects.select_related('artist').filter(artist=artist_id)
data = model_to_dict(artist)
给出以下错误'QuerySet' object has no attribute '_meta'
。我试着搜索这个错误,发现这个基本上建议使用get,这似乎违背了我发现的一切。
总而言之,我只是想选择一个艺术家和他们的作品,但我似乎不知道如何选择。
编辑-我尝试了一些事情并取得了一些进展,但它仍然不能正常工作
只是要清楚,我试图写一个查询,将通过他们的id查找艺术家,结果将是艺术家的信息和艺术家的作品。我可以根据artist_id或ArtistPiece
模型查询和检索Artist
模型,但没有一个查询将返回与该艺术家相关的Artist
和所有ArtistPiece
条目。
将related_name='pieces'
添加到我的模型中,如@bignose所建议的,然后我尝试了artist = Artist.objects.select_related('pieces').filter(pk=artist_id)
,但仍然没有给出属性....上面的错误。然后我将data = model_to_dict(artist)
更改为data = [model_to_dict(a) for a in artist]
,它工作了,但是数据只是艺术家而不是ArtistPiece
模型。
我没有查询Artist
模型,而是尝试查询ArtistPiece
模型:artist = ArtistPiece.objects.select_related('artist').filter(artist=artist_id)
,但是只返回了艺术家的作品,没有Artist
模型的信息。
model_to_dict
接受单个模型对象,但是您传入的是QuerySet
类型的对象(这与列表非常相似)。要获得所有对象的字典列表,需要显式地对每个模型对象调用model_to_dict
,如下所示:
data = [model_to_dict(a) for a in artist]
更好的方法是使用QuerySet.values()
作为:
data = artist.values()
根据Queryset.Values()
文件:
返回一个QuerySet,当用作可迭代对象时,返回字典,而不是模型实例。
每个字典代表一个对象,键对应于模型对象的属性名。
也看看Serializer
类。我想它会对你有用的。
ArtistPiece.objects.filter(artist=artist_id)
,这将返回一个查询集。
如果你想要一个列表,你可以做ArtistPiece.objects.filter(artist=artist_id).values_list('id', flat=True)
https://docs.djangoproject.com/en/1.10/ref/models/querysets/值列表
ForeignKey
字段类型还会自动设置外部模型的属性;在你的情况下,Artist.artistpieces_set
.
favourite_artist = Artist.objects.get(pk="foo") # However you get an Artist instance.
favourite_artist.artistpieces_set # Is a QuerySet of all the ArtistPiece instances that reference this instance.
# Because it's a QuerySet, you can iterate it, filter it, etc.
for piece in favourite_artist.artistpieces_set.all():
put_in_exhibition(piece)
因此,当您获得一个Artist
实例时,它自动具有一个属性,该属性是引用该Artist
的ArtistPiece
实例的QueryManager
。
这很好,因为它意味着外键关系在一个地方定义,但也可以从另一端访问。
关于如何使用这些特性,请参阅文档"向后遵循关系"。