在 Django 中使用“Self”关键字和一对多关系调用属性

Posted

技术标签:

【中文标题】在 Django 中使用“Self”关键字和一对多关系调用属性【英文标题】:Calling properties using "Self" keyword and One-To-Many Relationships in Django 【发布时间】:2021-02-16 17:07:04 【问题描述】:

我是 Django 新手,与 JS 或 C# 中的 this 相比,我很难理解 self 关键字的工作原理。我一直在研究Django REST API tutorial,现在正在尝试添加第二个模型类。我想在每个SnippetSubSnippets 之间建立一对多的关系,但想让我的SubSnippets 继承父Snippet 的语言和样式属性,以便我可以使用它们在每个SubSnippetformatter 中。这是我添加到models.py的代码:

class SubSnip(models.Model):
    snippet = models.ForeignKey(Snippet, on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    owner = models.ForeignKey('auth.User', related_name='sub-snippets', on_delete=models.CASCADE)
    highlighted = models.TextField()

    class Meta:
        ordering = ['snippet', 'created']

    def save(self, *args, **kwargs):
        lexer = get_lexer_by_name(self.snippet.language)
        linenos = 'table' if self.linenos else False
        options = 'title': self.title if self.title else 'snippet title': self.snippet.title
        formatter = htmlFormatter(style=self.snippet.style, linenos=linenos,
                                full=True, **options)
        self.highlighted = highlight(self.code, lexer, formatter)

问题在于 self.snippet.language 似乎没有调用实际的 Snippet 类,因为我收到一条错误消息,提示“ForeignKey 的实例没有‘语言’成员。”与self.snippet.titleself.snippet.style 相同。

我发现将所有模型放在一个文件中的约定有点奇怪,我想知道,从编译器 POV 来看,这是否就是我无法访问 Snippet 类的属性的原因。还是关于模型如何在 Django/Python 中工作的其他内容?我很想更深入地了解这里发生的事情!

【问题讨论】:

【参考方案1】:

这里有几个问题,所以我一次解决一个。

至于你的模型结构,你可以这样做:

请记住 - 在 python 中,当我们将对象传递给类声明时,该类将继承对象的属性、属性和方法。

# Snippet inherits the default django model:
class Snippet(models.Model):

    # fields:
    title = models.ChardField(...)
    ...

    # this simple method returns the title:
    def get_title(self): 
        return self.title

# SubSnippet inherits the Snippet class:
class SubSnippet(Snippet):

   # fields:
   snippet = models.ForeignKey('Snippet', ...)
   ...
  

现在我们可以像这样实例化一些实例:

# create a snippet:
snippet = Snippet.objects.create(
    title='I am the parent'
)

# create a subsnippet, and assign the above snippet as its 'parent':
subsnippet = SubSnippet.objects.create(
    title='I am the child', 
    snippet=snippet
)

# accessing fields:
print(subsnippet.title) # prints 'I am the child'
print(subsnippet.snippet.title) # prints 'I am the parent'
print(snippet.title) # prints 'I am the parent'

# using methods:
print(snippet.get_title()) # prints 'I am the parent'
print(subsnippet.get_title()) # prints 'I am the child' 

【讨论】:

以上是关于在 Django 中使用“Self”关键字和一对多关系调用属性的主要内容,如果未能解决你的问题,请参考以下文章

Python学习第130天(Django中ORM一对多的增删改查)

如何借助一对多关系在 Django 中使用外键从课程中获取主题

django2外键

Django Postgres ArrayField 与一对多关系

Django - 以一对多关系更改相关对象的值

如何在 django 中从一对多关系中检索数据?