代码之家  ›  专栏  ›  技术社区  ›  Kovy Jacob

引用导入的Django模型时,我收到“赋值前引用局部变量”错误

  •  0
  • Kovy Jacob  · 技术社区  · 5 月前

    我试图将一个模型导入到我的Django视图中,然后查询所有对象,对它们进行排序,并迭代它们。但是,在导入模型时,我没有遇到任何错误,在尝试使用以下命令查询模型时 songs = song.objects.all()#.order_by('-release_date') ,我收到一个错误:

    UnboundLocalError at /hotline/dbm
    local variable 'song' referenced before assignment
    /home/path/to/site/views.py, line 82, in dbm
    songs = song.objects.all()#.order_by('-release_date')
    

    我不明白问题是什么,因为变量 song 显然是从我的 models.py 文件,我在导入它时没有遇到任何错误——那么为什么Python无法识别它呢 歌曲 正如我从我的 models.py 文件?

    我的 models.py 文件:

    class song(models.Model):
        name = models.TextField()
        file = models.FileField()
        release_date = models.DateTimeField(default=timezone.now)
    
        class Meta:
            verbose_name = 'Song'
            verbose_name_plural = f'{verbose_name}s'
    

    我的 views.py 文件:

    #list of modules removed to keep code clean
    from .models import *
    
    @csrf_exempt
    def dbm(request: HttpRequest) -> HttpResponse:
        songs = song.objects.all()#.order_by('-release_date')
    
        response = request.POST.get('Digits')
    
        if response == None:
            vr = VoiceResponse()
    
            vr.say("Please choose a song, and then press pound")
            vr.pause(length=1)
    
            with vr.gather(finish_on_key='#', timeout=6, numDigits="1") as gather:
                for song, num in songs:
                    gather.pause(length=1)
                    gather.say(f"For {song.name}, please press {num}")
    
            vr.redirect(reverse('dbm'))
    
            return HttpResponse(str(vr), content_type='text/xml')
    
        elif response != None:
            vr = VoiceResponse()
            vr.say("hi")
    
            return HttpResponse(str(vr), content_type='text/xml')
    

    谢谢!

    2 回复  |  直到 5 月前
        1
  •  1
  •   willeM_ Van Onsem    5 月前

    我不明白问题是什么,因为变量歌曲显然是从我的models.py文件导入的

    是的 ,但在您的职能中,您还可以使用 地方的 变量名 song 事实上:

    for song, num in songs:
      # …

    这意味着Python说 歌曲 是a 地方的 变量,因此它拒绝在函数外寻找变量。

    但我认为主要问题是 班级 通常用 PascalCase ,不 snake_case ,所以你最好重命名模型 Song ,不 歌曲 由于局部变量已给出 蛇病例 名称,这样可以避免冲突,因此:

    #      🖟 not song
    class Song(models.Model):
        name = models.TextField()
        file = models.FileField()
        release_date = models.DateTimeField(default=timezone.now)
    
        class Meta:
            verbose_name = 'Song'
            verbose_name_plural = f'{verbose_name}s'

    那么视图看起来像:

    from .models import Song
    
    
    @csrf_exempt
    def dbm(request: HttpRequest) -> HttpResponse:
        songs = Song.objects..order_by('-release_date')
    
        response = request.POST.get('Digits')
    
        if response is None:
            vr = VoiceResponse()
    
            vr.say('Please choose a song, and then press pound')
            vr.pause(length=1)
    
            with vr.gather(finish_on_key='#', timeout=6, numDigits="1") as gather:
                for song, num in songs:
                    gather.pause(length=1)
                    gather.say(f"For {song.name}, please press {num}")
    
            vr.redirect(reverse('dbm'))
    
            return HttpResponse(str(vr), content_type='text/xml')
    
        else:
            vr = VoiceResponse()
            vr.say('hi')
    
            return HttpResponse(str(vr), content_type='text/xml')

    注: :请便 not use wildcard imports [quantifiedcode.com] . 它使语句的可预测性降低,如果您以后决定更改某个模块中导出的内容,则很容易导致代码失败,并且 此外,它还可以覆盖变量。

        2
  •  1
  •   Ashkan Khoshbash    5 月前

    在您的代码中,小写歌曲与类名冲突。

    使用时:

    from .models import *
    

    django导入歌曲类并将其分配给本地名称歌曲。

    for song, num in songs:
    

    然而,解释器假设函数中的song引用了一个局部变量(而不是模型类),因为for循环临时创建了一个本地变量

    在Django中,模型类应该遵循PascalCase命名约定。

    models.py:

    class Song(models.Model):
        name = models.TextField()
        file = models.FileField()
        release_date = models.DateTimeField(default=timezone.now)
    

    views.py

    from .models import Song
    
    @csrf_exempt
    def dbm(request: HttpRequest) -> HttpResponse:
        songs = Song.objects.all()#.order_by('-release_date')