代码之家  ›  专栏  ›  技术社区  ›  damon

在django中运行syncdb时找不到关系

  •  2
  • damon  · 技术社区  · 13 年前

    我在django应用程序的models.py中有这些类。我使用postgresql8.3作为数据库

    class Course(models.Model):
        students = models.ManyToManyField(User)
        title = models.CharField(max_length=200)
        description = models.TextField()
    
        def __unicode__(self):
            return self.title
    
        class Meta:
            verbose_name_plural="Courses"
    
    class CourseChoicesForm(forms.Form):
        courseoption = forms.ChoiceField(choices=[(x.id,x.title) for x in Course.objects.all()])
    

    当我跑步时 python manage.py syncdb ,我得到一个错误,上面写着 relation course is not found

    ...
    File "/home/me/Django-1.4/django/utils/importlib.py", line 35, in import_module
        __import__(name)
      File "/home/me/dev/python/django/myprj/myapp/models.py", line 50, in <module>
        class CourseChoicesForm(forms.Form):
      File "/home/me/dev/python/django/myprj/myapp/models.py", line 52, in CourseChoicesForm
        courseoption = forms.ChoiceField(choices=[(x.id,x.title) for x in Course.objects.all()])
    ...
    File "/home/me/Django-1.4/django/db/backends/postgresql_psycopg2/base.py", line 52, in execute
        return self.cursor.execute(query, args)
    django.db.utils.DatabaseError: relation "myapp_course" does not exist
    

    更新: 我解决这个问题如下

    class CourseChoicesForm(forms.Form):
        courseoption = forms.ChoiceField(choices=[],required=False)
        def __init__(self, *args, **kwargs):
            super(CourseChoicesForm, self).__init__(*args, **kwargs)
            self.fields['courseoption'].choices = [(x.id,x.title) for x in Course.objects.all()]
    

    尽管如此,我还是不太清楚为什么会发生这种行为。有人能解释一下吗?

    1 回复  |  直到 13 年前
        1
  •  3
  •   Ian Clelland    13 年前

    把表单放在models.py文件中不是一种好的做法,这正是为什么。

    对于 syncdb 要运行,它首先需要加载模型文件。在进行任何数据库更新之前,这肯定必须发生。

    现在,您的models.py文件 而且 包括一个表单类,而该类定义依赖于当前的表。(这只是Python工作方式的一部分——类定义是在导入模块时执行的)。因此,在添加该表之前, 同步数据库 必须加载一个要求表存在的模块。

    当您更改窗体类时,您移动了依赖于新表的行——现在它位于 __init__ 方法与班级不同 释义 ,该方法不会在导入时运行。它仅在实际创建表单对象时运行。现在 同步数据库 可以导入您的新模块并更新数据库,一切正常。