【问题标题】:Django model doesn't save only after queryDjango模型仅在查询后才保存
【发布时间】:2016-03-01 20:21:13
【问题描述】:

我已经在 Django 上工作了一段时间,现在我遇到了这个奇怪的问题。

我正在一个流媒体网站上添加评分功能,为此我编写了一个通过 url 调用的视图:

url(r'^channel/rate/(?P<stream_id>[\d]*)/(?P<rate>[\d]*)/?$', 'eros.streaming.views.view_rate_channel', 
   name='view_rate_channel'),

def view_rate_channel(request,stream_id,rate):
    if(stream_id and rate and request.user.is_authenticated()):
        stream= Stream.objects.get(id=stream_id)
        if stream not in request.user.channel.rated_streams.all():
            if stream.channel.user != request.user:
                channel=Channel.objects.get(stream=stream)
                channel.rating= channel.rating+int(rate)    
                print("channel rating:   "+str(channel.rating))
                #this prints fine in any case
                channel.n_voters = channel.n_voters +1
                channel.save()
                stream.rating= stream.rating+int(rate)
                stream.n_voters= stream.n_voters+1
                stream.save()    
                request.user.channel.rated_streams.add(stream)
                request.user.channel.save()
                return HttpResponseRedirect('/channel/'+str(stream.channel.id)+'/')  
    return HttpResponseRedirect('/channel/'+str(stream.channel.id)+'/')

当我检查数据库时,我在 channel.save() 之后对 Channel 对象所做的更改没有保存,只有我发现奇怪的 Stream 对象上的更改。

所以在进行了一些调试之后,我决定评论这个 if,我使用它以便用户不能对流进行多次评分:

        ##if stream not in request.user.channel.rated_streams.all():

现在 channel.save() 开始工作了!坏事是我不能让用户对流进行多次评分。

这是模型的简化版本:

class Channel(models.Model):
    user = models.OneToOneField(User)
    rating = models.IntegerField(default=0)
    n_voters = models.IntegerField(default=0)
    rated_streams = models.ManyToManyField('Stream', related_name="rated_streams")
    description = models.TextField(default="")

class Stream(models.Model):
    ## I think that maybe this relation is what is causing me trouble (?):
    channel = models.ForeignKey(Channel)
    rating = models.IntegerField(default=0)
    n_voters = models.IntegerField(default=0)

我正在做的任何不良做法或不良查询导致这种情况发生吗?提前非常感谢。

【问题讨论】:

  • if stream 条件未注释时,Channel 对象中的更改不会被保存。是这个问题吗?
  • Channel.objects.get(stream=stream) 是如何工作的?没有stream 列是您的Channel 模型。
  • 另外,您确认channelrequest.user.channel 是同一个对象吗?
  • 关于您的第二条评论,这是一件有趣的事情,因为关系是用流上的外键(一对多)建模的,通道上没有字段流。所以我尝试让通道作为参数传递流并返回它,但这是一种愚蠢的调用方式,因为我可以像 channel=stream.channel 一样做到这一点。我做到了并且知道它的工作原理!这是一种奇怪的行为。非常感谢!
  • 好的,伙计!你的意思是在下面的答案中?

标签: python django django-models django-views django-queryset


【解决方案1】:

使用channel = stream.channel 而不是channel = Channel.objects.get(stream=stream) 解决了这个问题。

【讨论】:

  • 这将允许其他行执行,例如 channel.rating=channel.rating+int(rate),只有在用户尚未对流进行评分时才会发生这种情况。
  • 一个频道有很多流,每次用户对一个流进行评分时,它也会对频道进行评分,但一个流只能被评分一次。用户可以对频道的许多流进行评分。
  • 如果请求的stream 已被用户评分,我们是否应该更改channel 速率(跳过流中的更改)?
  • 如果用户已经对流进行了评级,则频道速率不会改变,只有在要对新流进行评级时才会改变。
猜你喜欢
  • 1970-01-01
  • 2021-11-12
  • 2018-02-13
  • 2021-03-26
  • 1970-01-01
  • 2016-10-03
  • 2023-03-23
  • 2017-08-10
  • 2015-07-13
相关资源
最近更新 更多