this回答之后,我试图将SQL Story表拆分为父级/子级-子级保存特定的用户数据,而父级则保存更多的通用数据。现在,我遇到了一个问题,出了我缺乏Django经验的问题。我的用户页面尝试显示用户编写的所有故事的列表。以前,当我的用户页面仅从故事表中提取数据时,它运行良好。现在,我需要从两个具有链接信息的表中提取数据,但我不知道该怎么做。

这也是我的user_page视图,也试图从父故事表中提取数据:

def user_page(request, username):
    user = get_object_or_404(User, username=username)
    userstories = user.userstory_set.order_by('-id')
    variables = RequestContext(request, {
    'username': username,
    'userstories': userstories,
    'show_tags': True
    })
    return render_to_response('user_page.html', variables)


这是我的models.py:

class story(models.Model):
    title = models.CharField(max_length=400)
    thetext = models.TextField()

class userstory(models.Model):
    main = models.ForeignKey(story)
    date = models.DateTimeField()
    user = models.ForeignKey(User)


从父表中查找适当的信息并将其分配给变量,我真的不知道从哪里开始。我需要做的是按照用户表的“主”键进入故事表,并将故事表分配为变量。但是我只是看不到如何在定义中实现它。

编辑:我已经尝试了故事= userstory.objects.get(user = user),但我得到了'userstory匹配查询不存在'。

最佳答案

通读您链接到的上一个问题,我发现了混乱所在。我的印象是Story可能有许多与之相关的UserStory。请注意,我使用Capital作为类名,这是Python的常见做法。我做这个假设是因为您的模型结构允许通过在UserStory模型中使用外键来实现这一点。您的模型结构应如下所示:

class Story(models.Model):
    title = models.CharField(max_length=400)
    thetext = models.TextField()

class UserStory(models.Model):
    story = models.OneToOneField(Story) # renamed field to story as convention suggests
    date = models.DateTimeField()
    user = models.ForeignKey(User)

class ClassicStory(models.Model)
    story = models.OneToOneField(Story)
    date = models.DateTimeField()
    author = models.CharField(max_length=200)


请参见OneToOne relationships here的用法。 “一对一”字段表示一对一关系,这意味着一个故事只有一个用户故事,只有一个。这也意味着UserStory与一个故事完全相关。这是“父母-孩子”关系,另外的约束是父母只有一个孩子。您之前使用ForeignKey意味着一个Story有多个与之关联的UserStories,这对于您的用例是错误的。

现在,您的查询(和属性访问器)将表现出预期的效果。

# get all of the users UserStories:
user = request.user
stories = UserStory.objects.filter(user=user).select_related('story')

# print all of the stories:

for s in stories:
    print s.story.title
    print s.story.thetext


请注意,select_related将创建一个SQL连接,因此您每次打印出故事文本时都不会执行另一个查询。阅读有关此内容,这非常非常非常重要!

您先前的问题提到您还有另一个表ClassicStories。就像UserStories一样,它也应该有一个OneToOneField。以这种方式使用OneToOne字段将很难遍历Story模型,因为它可能是“ ClassicStory”,但可能是“ UserStory”:

# iterate over ALL stories

allstories = Story.objects.all()
for s in allstories:
    print s.title
    print s.thetext
    print s.userstory     # this might error!
    print s.classicstory  # this might error!


看到问题了吗?您不知道这是什么样的故事。在访问子表中的字段之前,需要检查故事的类型。有一些项目可以帮助您管理此类继承,例如django-model-utils InheritanceManager,但这有点先进。如果您永远不需要遍历Story模型并访问其子表,则无需担心。只要您仅访问ClassicStories或UserStories中的Story,就可以了。

10-02 06:18
查看更多