1

按照这个答案,我尝试将我的 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)

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

编辑:我试过 story = userstory.objects.get(user=user) 但我得到“用户故事匹配查询不存在”。

4

1 回答 1

1

阅读您之前链接到的问题,我发现了困惑所在。我的印象是 aStory可能有很多UserStory与之相关的 s。请注意,我使用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 关系的使用。OneToOne 字段表示一对一的关系,这意味着一个 Story 有一个且只有一个 UserStory。这也意味着一个 UserStory 只与一个 Story 相关。这就是“父子”关系,额外的限制是父母只有一个孩子。您之前使用 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。它还应该有一个 OneToOneField,就像 UserStories 一样。以这种方式使用 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,就可以了。

于 2013-10-21T22:31:08.950 回答