【问题标题】:Django: If user has entered address previouslyDjango:如果用户以前输入过地址
【发布时间】:2011-05-18 05:57:45
【问题描述】:

如果用户之前没有在登录时填写过,我想向他展示一个表单,但如果他之前填写过信息,我想将他重定向到主页。 我如何做到这一点?

这是我的看法:

def makinginfo(request):
    form = SongForm(request.POST or None)
    songprofile =  SongProfile.objects.get().filter(user=request.user)
    if songprofile = null: IS THIS RIGHT?     
        if form.is_valid():
            form.save()
            sp = SongProfile
            sp.song = form.pk
            sp.save()
            if 'next' in request.POST:
               next = request.POST['next']
            else:
               next = reverse('index_show')
               return HttpResponseRedirect(next)
        return render_to_response(
        'song/create.html',
           {'form':form},

             context_instance = RequestContext(request)
               )

     else:
        return render_to_response(
        'song/show.html',
         context_instance = RequestContext(request)
               )

我在正确的轨道上吗?

谢谢,

附加信息:

SongProfile 和 Song 是两个不同的模型。 SongProfile 模型如下: class SongProfile(models.Model): song = models.OneToOneField(Song) 因此,当我尝试同时保存歌曲和歌曲配置文件时,其中歌曲配置文件保存了歌曲中创建的记录的最新 id/pk。这是错的吗?

【问题讨论】:

  • 1) 您不需要.get()。让它只是 SongProfile.objects.filter(user=request.user) 2) null 在 Python 中不存在。等价于None,但您只需检查if songprofile: 3) 一般而言,一对一关系仅在您需要向不受控制的模型添加信息时才值得。如果您同时控制两者,SongProfile 上的字段应该继续Song。 4)您缺少最后一个render_to_response 上的数据字典参数,如果您不需要任何东西,请传递一个空字典({})。

标签: django django-templates django-forms django-views


【解决方案1】:

我假设每个用户只有一个 SongProfile 对象。

 try:
    songprofile = SongProfile.objects.get(user=request.user)
    # Render song/show.html
 except SongProfile.DoesNotExist:
   if form.is_valid():
      # Process post

   # Render song/create.html

用表单创建的 Song 创建一个新的 SongProfile 对象:

 song = form.save()
 songprofile = SongProfile(user=request.user)
 songprofile.song = song
 songprofile.save()

再次编辑:

修复了向后的东西并添加了 Song 对象。

【讨论】:

  • @Natim 那是songprofile = null 的语法正确版本,是的,但是当使用get() 时,不存在的结果会引发异常——不返回null。
  • 是的,我知道你的答案很好:) 我只是告诉他,因为他问是否正确。
  • SongProfile 和 Song 是两个不同的模型。 SongProfile 模型如下:class SongProfile(models.Model): song = models.OneToOneField(Song) 所以当我尝试同时保存歌曲和歌曲配置文件时,其中 songprofile.song 保存歌曲中创建的记录的最新 id/pk。这是错的吗?
  • 也不应该反过来... songprofile.doesnotexist 应该呈现表单并处理帖子?
【解决方案2】:

您确实可以像 Tim 演示的那样执行 try/catch,这将起作用。如果您发现在某些情况下您开始过滤更多字段或者您想要一个合理的默认值,您可以按照文档的建议进行操作并使用get_or_create() 方法,如下所示:

sp, created = SongProfile.objects.get_or_create(user=request.user)

来自docs:

任何传递给 get_or_create() 的关键字参数——除了一个称为默认值的可选参数——都将在 get() 调用中使用。如果找到一个对象,get_or_create() 将返回该对象的元组和 False。如果找不到对象,get_or_create() 将实例化并保存一个新对象,返回一个新对象的元组和 True。

所以布尔值表示是否需要创建对象,您可以使用它来指导方法逻辑。

这种语法也更简洁明了。

就试图同时保存Song 和SongProfile 而言,不,你没有错。正如 Tim 演示的那样,form.save() 创建了新的 song 和 songprofile.song = song,然后是 songprofile.save(),保存了 songprofile 的歌曲参考。

代码示例中有几个小错误。一个错误是,

if songprofile = null:
    ...

正如@Natim 所说,你应该使用哪个,

if songprofile is None:
    ...

还有一个问题,

sp = SongProfile

哪个 Python 确实会编译,但是它将 SongProfile 类对象引用分配给变量而不是类本身的实例。你通常想要做的是,

sp2 = SongProfile()

这将创建对象实例。如果您执行dir(sp) 和dir(sp2),您会看到区别。

【讨论】:

    猜你喜欢
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 2011-07-23
    • 2014-07-15
    • 1970-01-01
    相关资源
    最近更新 更多