Python Django-通过OneToOneField访问属性

Python Django-通过OneToOneField访问属性,python,django,django-models,Python,Django,Django Models,我对Django很陌生,我想知道我是否可以就我面临的问题寻求一些帮助。我试图在Django中构建一组模型,其结构如下: app\u用户描述我正在构建的应用程序的用户。 app\u作业描述了用户希望在应用程序上运行的作业,以及若干相关输入(upload1,upload2,upload3)。一个用户可以运行多个作业;因此,我使用作业和用户之间的多对一(ForeignKey)关系。创建app_作业时,我希望将其关联文件上载到由关联用户的用户名和num_作业属性确定的目录,如图所示 运行python m

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

app\u用户
描述我正在构建的应用程序的用户。
app\u作业
描述了用户希望在应用程序上运行的作业,以及若干相关输入(
upload1
upload2
upload3
)。一个用户可以运行多个作业;因此,我使用作业和用户之间的多对一(
ForeignKey
)关系。创建
app_作业
时,我希望将其关联文件上载到由关联用户的
用户名
num_作业
属性确定的目录,如图所示

运行
python manage.py makemigrations
时,我收到以下错误:
AttributeError:“ForeignKey”对象没有属性“user”
。这就引出了一个问题:如何从
app\u作业
类中访问底层
app\u用户的信息

谢谢你的帮助

# 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) )
基于这样的情况,应该可以:

# 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)    

好的,这里有几个问题。但没有一点教育不能解决的问题

  • 模型应该用骆驼套,这样更容易阅读,通常是一种很好的做法
  • 您不需要在模型前面加上
    app
    前缀,没有这个前缀,它更清晰、更容易阅读

反正

您的
app\u作业
model外键应指向
User
而不是
app\u用户
模型。通过这样做,您仍然可以访问
app\u用户
数据

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

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

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)

正如你所知道的,有几个问题。但这很好学:)

首先,类名应以大写字母开头,并使用“camelCase”, 在您的例子中,“AppUser”和“AppJob”。就我个人而言,我不会用“App”作为后缀,而是用“MyUser”和“Job”

“ForeignKey”对象没有属性“user”时出现的错误是因为在“app_作业”模型中,您有一个ForeignKey to app_user,这可以创建两个模型之间的关系,但在文件字段中,您使用的是与模型“app_user”同名的“ForeignKey”对象那个ForeignKey实例并没有一个名为“user”的属性,你们明白了吗

那些家伙给你的关于“上传到”的信息是正确的:)。 你可以在网站上获得更多信息


谢谢

问题不在于访问相关数据,而在于尝试访问类定义中的实例属性数据。1:类名应为CAMEL CASE。第二:@DMunoz类
AppJob
中没有名为user的属性。第三:
upload\u to
可以是可调用的,但您拥有的是表达式,而不是可调用的。第四点:确保在创建用户时创建了一个
app\u用户
实例。可以实现(例如,用户上的
post\u save
# 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)