Django - 通过OneToOneField访问属性

时间:2015-07-29 19:28:33

标签: python django django-models

我对Django很新,我想知道我是否可以就我面临的问题寻求帮助。我试图在Django中构建一组模型,其结构如下:

app_user描述了我正在构建的应用程序的用户。 app_job描述了用户想要在应用上运行的作业,其中包含多个相关输入(upload1upload2upload3)。用户可以运行许多工作;因此,我使用作业和用户之间的多对一(ForeignKey)关系。创建app_job后,我希望将其关联文件上传到由关联用户的usernamenum_jobs属性确定的目录,如图所示。

当我运行python manage.py makemigrations时,收到以下错误:AttributeError: 'ForeignKey' object has no attribute 'user'。这引出了一个问题,如何从app_user类访问基础app_job的信息?

感谢您的帮助。

# models.py

from django.db import models
from django.contrib.auth.models import User

from django.forms import ModelForm

class app_user(models.Model):
    user = models.OneToOneField(User)
    num_jobs = models.IntegerField(default = 0)

    def __unicode__(self):
        return self.user.get_username()


class app_job(models.Model):
    app_user = models.ForeignKey(app_user)
    upload1 = models.FileField(upload_to = app_user.user.get_username() + "/" + str(app_user.num_jobs) , blank = True, null = True)
    upload2 = models.FileField(upload_to = app_user.user.get_username() + "/" + str(app_user.num_jobs))
    upload3 = models.FileField(upload_to = app_user.user.get_username() + "/" + str(app_user.num_jobs) )

3 个答案:

答案 0 :(得分:4)

好的,这里有几个问题。但是没有什么教育无法解决。

  • 模型应该是CamelCased,这使得它更容易阅读,并且通常是很好的做法。
  • 如果没有这个,{1>你不需要为模型添加前缀app_更清晰,更容易阅读。

反正

app_job模型的ForeignKey应该是User而不是app_user模型。通过这样做,您仍然可以访问app_user数据。

您还需要修改upload_to属性。虽然uploads_to可以是字符串值,但它无法按照您当前的方式进行评估。查看django filefield documentation了解详细信息(无耻插件,我最近重写了这部分文档)。

相反,您需要执行以下操作:

def user_directory_path(instance, filename):
    # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
    return 'user_{0}/{1}'.format(instance.user.id, filename)

class app_job(models.Model):
    app_user = models.ForeignKey(User)
    upload1 = models.FileField(upload_to=user_directory_path , blank = True, null = True)
    upload2 = models.FileField(upload_to=user_directory_path
    upload3 = models.FileField(upload_to=user_directory_path, blank=True, null=True)

这样做upload_to调用函数user_directory_path来生成文件路径。

通过以上内容,你应该有:

# models.py

from django.db import models
from django.contrib.auth.models import User

from django.forms import ModelForm

class UserProfile(models.Model):
    """
    In settings.py you will want to add a link to AUTH_USER_PROFILE 
    See https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#extending-the-existing-user-model
    """
    user = models.OneToOneField(User)
    num_jobs = models.IntegerField(default=0)

    def __unicode__(self):
        return self.user.get_username()

def upload_dir(instance, filename):
    return instance.user.get_username() + "/" + str(instance.user.num_jobs)

class Job(models.Model):
    user = models.ForeignKey(User)
    upload1 = models.FileField(upload_to=upload_dir, blank = True, null = True)
    upload2 = models.FileField(upload_to=upload_dir, blank=True, null=True)
    upload3 = models.FileField(upload_to=upload_dir, blank=True, null=True)

答案 1 :(得分:1)

基于this answer to a similar question这样的事情应该有效:

# models.py

from django.db import models
from django.contrib.auth.models import User

class app_user(models.Model):
    user = models.OneToOneField(User)
    num_jobs = models.IntegerField(default = 0)

    def __unicode__(self):
        return self.user.get_username()

def content_file_name(instance, filename):
    return '/'.join([instance.app_user.user.get_username(), str(instance.app_user.num_jobs), filename])

class app_job(models.Model):
    app_user = models.ForeignKey(app_user)
    upload1 = models.FileField(upload_to = content_file_name , blank = True, null = True)
    upload2 = models.FileField(upload_to = content_file_name)
    upload3 = models.FileField(upload_to = content_file_name)    

答案 2 :(得分:0)

正如您所知,有几个问题。但它的好处是:)。

首先,班级名称应以大写字母开头,并使用&#34; camelCase&#34;, 在你的情况下,&#34; AppUser&#34;和#34; AppJob&#34;。我个人不会使用&#34; App&#34;作为后缀,我只会使用&#34; MyUser&#34;和&#34;工作&#34;。

你得到的错误&#34;&#39; ForeignKey&#39;对象没有属性&#39; user&#34;是因为在你的&#34; app_job&#34;模型你有一个ForeignKey到app_user,这是可以的,它创建了两个模型之间的关系,但然后在FileField你正在使用&#34; foreignkey&#34;与您的模型同名的对象&#34; app_user&#34;而且ForeignKey实例没有名为&#34; user&#34;的属性,你知道吗?

这些人给你的信息与&#34; upload_to&#34;是正确的 :)。 您可以在Django docs

中获取更多信息

由于