天道酬勤,学无止境

Django - 从实例访问模型“通过”表上的字段(Django - Access fields on a model's "through" table from an instance)

问题

我与直通表有多对多关系,如下所示:

class Chapter(models.Model):
    name = models.CharField(max_length=255,)
    slides = models.ManyToManyField('Slide', blank=True, related_name='chapters', through='SlideOrder')
    # ...

class Slide(models.Model):
    title = models.CharField(max_length=255,)
    # ...

class SlideOrder(models.Model):
    chapter = models.ForeignKey(Chapter)
    slide = models.ForeignKey(Slide)
    number = models.PositiveIntegerField()

我可以按顺序获取一章的幻灯片,如下所示:

chapter = Chapter.objects.get(pk=1)
chapter_slides = chapter.slides.order_by('slideorder')

但是,在处理单个幻灯片实例时,我无法访问幻灯片顺序:

slide = Slide.objects.get(pk=1)

如果我在幻灯片实例上执行以下操作,我可以看到所有可能的字段:

print slide._meta.get_all_field_names()
['title', u'chapters', 'slideorder', u'id']

但是,尝试访问slideorder字段给了我以下信息:

slide.slideorder
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Slide' object has no attribute 'slideorder'

我能够访问除slideorder之外列出的所有属性。 如何访问幻灯片的顺序?

回答1

您可以直接在SlideOrder模型上进行过滤

slide = Slide.objects.get(pk=1)
slide_orders = SlideOrder.objects.filter(slide=slide)
for slide_order in slide_orders:
    print slide_order.number

或向后跟随外键:

slide = Slide.objects.get(pk=1)
slide_orders = slide.slideorder_set.all()
for slide_order in slide_orders:
    print slide_order.number

有关更多信息,请参阅有关多对多关系的额外字段的文档。

回答2

您可以使用 django 文档中记录的slide.slideorder_set

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • on_delete对Django模型有什么作用?(What does on_delete do on Django models?)
    问题 我对Django非常熟悉,但是最近我注意到on_delete=models.CASCADE存在on_delete=models.CASCADE选项。 我已经搜索了相同的文档,但是除了以下内容外,我什么也找不到: 在Django 1.9中进行了更改: 现在可以将on_delete用作第二个位置参数(以前通常仅将其作为关键字参数传递)。 在Django 2.0中,这是必填参数。 用法示例是: from django.db import models class Car(models.Model): manufacturer = models.ForeignKey( 'Manufacturer', on_delete=models.CASCADE, ) # ... class Manufacturer(models.Model): # ... pass on_delete是做什么的? (我猜想如果删除模型,应该执行的操作。) models.CASCADE什么作用? (文档中的任何提示) 还有其他可用的选项(如果我的猜测是正确的)? 有关此文档的位置在哪里? 回答1 这是删除引用对象时要采取的行为。 它不是特定于Django的。 这是一个SQL标准。 尽管Django在SQL之上有自己的实现。 (1) 发生此类事件时,可以采取七种可能的措施: CASCADE :删除引用的对象时
  • on_delete 对 Django 模型有什么作用?(What does on_delete do on Django models?)
    问题 我对 Django 非常熟悉,但我最近注意到on_delete=models.CASCADE有一个on_delete=models.CASCADE选项。 我已经搜索了相同的文档,但除了以下内容之外我什么也找不到: 在 Django 1.9 中更改: on_delete现在可以用作第二个位置参数(以前它通常只作为关键字参数传递)。 这将是 Django 2.0 中的必需参数。 一个使用案例是: from django.db import models class Car(models.Model): manufacturer = models.ForeignKey( 'Manufacturer', on_delete=models.CASCADE, ) # ... class Manufacturer(models.Model): # ... pass on_delete 有什么作用? (我猜如果删除模型要执行的操作。) models.CASCADE什么作用? (文档中的任何提示) 还有哪些其他选项可用(如果我的猜测是正确的)? 这方面的文档在哪里? 回答1 这是删除引用对象时要采用的行为。 它不是 Django 特有的; 这是一个 SQL 标准。 尽管 Django 在 SQL 之上有自己的实现。 (1) 发生此类事件时,可以采取七种可能的操作: CASCADE
  • Django模型层---文档笔记
    基于对象 反向查询的时候 当你的查询结果可以有多个的时候 就必须加_set.all() 当你的结果只有一个的时候 不需要加_set.all() 模型是你的数据唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。 每个模型都是django.db.models.Model的一个python子类,模型的每个属性都表示数据库中的一个字段。每个字段都被指定成一个类属性,字段名称不要和模型API冲突。Django提供了一套自动生成的用户数据库访问的API。 数据库表的名称是根据模型中的元数据自动生成的,也可以覆写为别的名字。id字段是自动添加的,这个行为也可以被重写。Django会根据设置文件中指定的数据库类型来使用相应的SQL语句。 定义好模型后要使用应用中的模型需要在配置文件的INSTALLED_APPS选项中添加相应的应用名称app.Config/app。添加完应用名,makemigrations生成迁移文件,migrate进行数据库迁移。 模型中每个字段都是Field子类的某个实例。Django根据字段类的类型确认以下信息: 1数据库当中的列类型 (比如, INTEGER , VARCHAR )。 2渲染表单时使用的默认HTML部件(例如,, )。 3最低限度的验证需求,它被用在 Django 管理站点和自动生成的表单中。
  • 创建Django表格(creating django forms)
    问题 我正在努力弄清django表格。.我一直在阅读各种文档,但只是不太了解这些概念。 我必须掌握模型,视图和模板。 我想要做的是创建一个包含由下拉列表和复选框组成的各种字段的表单,这些列表由数据库中的值填充。 我有一个名为vms的工作应用程序。 使用models.py,我构建了一个包含大小和类型的简单架构。 大小由“小”,“中”和“大”组成。 类型是“ windows”和“ linux”。 使用管理网站,我可以添加一个额外的大小,例如“特大”。 我想做的是创建一个具有vm大小下拉列表的表单。 如果通过管理网站添加了额外的尺寸,我希望该尺寸显示在下拉列表中。 我会尝试编写代码,但实际上在概念上挣扎。 谁能帮助我完成上述任务? 谢谢奥利 回答1 表单只是一种工具,用于简化和加速从请求中获取POST数据的过程(开发)。 手动方式是对所有以HTML格式存在的字段执行request.POST.get('somefield') 。 但是Django可以做得更好... 本质上,Form类包含许多Field并执行以下任务: 显示HTML输入, 用户提交数据时收集并验证数据, 如果字段未通过验证,则将值和错误消息返回到HTML, 如果所有字段都通过验证,则提供form.cleaned_data字典,作为在视图中访问这些值的便捷方法。 使用这些值,然后可以手动创建MyModel的新实例并保存它。
  • Django中的OneToOne,ManyToMany和ForeignKey字段有什么区别?(Whats the difference between a OneToOne, ManyToMany, and a ForeignKey Field in Django?)
    问题 我很难理解Django模型中的关系。 有人可以解释一下OneToOne,ManyToMany和ForeignKey之间的区别吗? 回答1 好吧,这里基本上有两个问题: 一对一,多对多和外键关系之间的区别(通常)是什么它们对Django有什么区别。 通过简单的Google搜索,可以很容易地回答这两个问题,但是由于我在SO上找不到该问题的确切答案,因此我将继续回答。 请注意,在Django中,关系只能在关系的一侧定义。 外键 外键关系通常称为多对一关系。 请注意,这种关系的反面是一对多(Django提供了访问工具)。 顾名思义,许多对象可能与一个对象相关。 Person >--| Birthplace ^ ^ | | Many One 在此示例中,一个人可能只有一个出生地,但是一个出生地可能与许多人有关。 让我们看一下Django中的这个例子。 说这些是我们的模型: class Birthplace(models.Model): city = models.CharField(max_length=75) state = models.CharField(max_length=25) def __unicode__(self): return "".join(self.city, ", ", self.state) class Person(models.Model): name
  • Django 代理模型和外键(Django proxy model and ForeignKey)
    问题 如何使 entry.category 成为 CategoryProxy 的实例? 详情见代码: class Category(models.Model): pass class Entry(models.Model): category = models.ForeignKey(Category) class EntryProxy(Entry): class Meta: proxy = True class CategoryProxy(Category): class Meta: proxy = True entry = EntryProxy.objects.get(pk=1) entry.category # !!! I want CategoryProxy instance here 从 Category 转换到 CategoryProxy 也可以,但我对 ORM 内部结构不太熟悉以正确复制内部状态...... 编辑。 原因:我给CategoryProxy加了方法,想用他: EntryProxy.objects.get(pk=1).category.method_at_category_proxy() 编辑 2.目前我是这样实现的: EntryProxy._meta.get_field_by_name('category')[0].rel.to =
  • 如何自省Django模型字段?(How to introspect django model fields?)
    问题 当我只知道字段名称和模型名称(均为纯字符串)时,我试图获取模型内部字段上的类信息。 这怎么可能? 我可以动态加载模型: from django.db import models model = models.get_model('myapp','mymodel') 现在我有一个字段-'myfield'-如何获取该字段的类? 如果该字段是相关的-如何获取相关字段? 谢谢一堆! 回答1 您可以使用模型的_meta属性来获取字段对象,并可以从字段中获得关系以及更多信息,例如,考虑一个雇员表,该雇员表具有一个部门表的外键 In [1]: from django.db import models In [2]: model = models.get_model('timeapp', 'Employee') In [3]: dep_field = model._meta.get_field_by_name('department') In [4]: dep_field[0].target_field Out[4]: 'id' In [5]: dep_field[0].related_model Out[5]: <class 'timesite.timeapp.models.Department'> 来自django / db / models / options.py def get
  • 如何从Django访问PostGIS数据库中的几何(点)字段?(How to access a geometry (point) field in PostGIS database from Django?)
    问题 在我的项目中,我使用PostgreSQL / PostGIS作为数据库,并使用django.contrib.gis配置的Django。 现有的表pois包含地理空间点数据。 以下是SQL create语句的摘录: CREATE TABLE pois ( ogc_fid serial NOT NULL, the_geom geometry(Point,900914), name character varying(254), -- ... 我使用以下命令生成了Django模型: $ python manage.py inspectdb 生成的模型如下所示: from django.contrib.gis.db import models class POIs(models.Model): ogc_fid = models.AutoField(primary_key=True) the_geom = models.TextField(blank=True, null=True) # This field type is a guess. name = models.CharField(max_length=254, blank=True, null=True) class Meta: managed = False db_table = 'pois'
  • Django Rest Framework Serializers API指南
    官方文档链接 Serializers 序列化器 前言: 序列化器允许诸如查询集和模型实例复杂的数据转换为原生的Python数据类型,然后可以很容易地呈现为JSON,XML或其他内容类型。序列化器还提供反序列化功能,允许在首先验证输入数据之后将解析的数据转换回复杂类型。 REST框架中的序列化器的工作方式与Django Form和ModelForm类非常相似。我们提供了一个Serializer类,该类为您提供了一种强大的通用方法来控制响应的输出,还ModelSerializer提供了一个类,该类为创建用于处理模型实例和查询集的序列化器提供了有用的快捷方式。 声明序列化器 让我们从创建一个简单的对象开始,我们可以将其用于示例目的: from datetime import datetime class Comment(object): def __init__(self, email, content, created=None): self.email = email self.content = content self.created = created or datetime.now() comment = Comment(email='leila@example.com', content='foo bar') 我们将声明一个序列化器
  • 获取django中的用户个人资料(get user profile in django)
    问题 你好,我是python和django的新手,我需要一个获取当前用户配置文件的视图,我知道我应该使用User的get_profile,但我不知道如何使用它。 我读了django文件,但并没有帮助我。 这是我从doc中找到的: from django.contrib.auth.models import User profile=request.user.get_profile() 回答1 Django的文档说明了一切,尤其是存储有关用户的其他信息的部分。 首先,您需要在models.py某个地方定义一个模型,其中包含用于用户的其他信息的字段: models.py from django.contrib.auth.models import User class UserProfile(models.Model): # This field is required. user = models.OneToOneField(User) # Other fields here accepted_eula = models.BooleanField() favorite_animal = models.CharField(max_length=20, default="Dragons.") 然后,您需要通过在settings.py设置AUTH_PROFILE_MODULE来表明该模型(
  • 如何访问 DRF 中 ListSerializer 父类上的 serializer.data?(How to access serializer.data on ListSerializer parent class in DRF?)
    问题 在Response(serializer.data, status=something)返回之前尝试访问serializer.data时出现错误: 尝试获取序列化程序<serializer>上的字段<field>的值时出现 KeyError。 这发生在所有字段上(因为事实证明我正在尝试访问父级而不是子级的.data ,见下文) 类定义如下所示: class BulkProductSerializer(serializers.ModelSerializer): list_serializer_class = CustomProductListSerializer user = serializers.CharField(source='fk_user.username', read_only=False) class Meta: model = Product fields = ( 'user', 'uuid', 'product_code', ..., ) CustomProductListSerializer是一个serializers.ListSerializer并且有一个重写的save()方法,允许它正确处理批量创建和更新。 这是来自批量 Product ViewSet的示例视图: def partial_update(self, request)
  • Django删除FileField(Django delete FileField)
    问题 我正在Django中构建一个Web应用程序。 我有一个上传文件的模型,但是我不能删除该文件。 这是我的代码: class Song(models.Model): name = models.CharField(blank=True, max_length=100) author = models.ForeignKey(User, to_field='id', related_name="id_user2") song = models.FileField(upload_to='/songs/') image = models.ImageField(upload_to='/pictures/', blank=True) date_upload = models.DateField(auto_now_add=True) def delete(self, *args, **kwargs): # You have to prepare what you need before delete the model storage, path = self.song.storage, self.song.path # Delete the model before the file super(Song, self).delete(*args, **kwargs) # Delete the
  • Django:试图从另一个表(FK)中获取最后一个字段的值并添加到我的模型中(Django: Trying to get last field's value from another table (FK) and add to my model)
    问题 我有 2 个表,关系是一对多的,“Book”(id、name、author)->“BookStatus”(id、status、date)。 我想在查询集中获取所有具有 LAST 状态(根据字段“日期”)的书籍。 我怎样才能做到这一点? 在那之后,我怎么能通过我的模型“书”显示那个字段(状态),比如 Book.last_status。 提前致谢 回答1 不幸的是,通过 ORM 做到这一点并不容易。 原因是为此所需的 SQL 非常复杂。 首先您需要获取最新的状态日期,然后加入与该状态匹配的状态。 如果您只需要访问 Python 端的最新状态,那么您可以使用 book.statuses.latest()(为每个模型生成一个查询),或者可能是模型上的一个属性: @property def latest_status(self): latest_status = None for status in self.statuses.all(): if latest_status is None or latest_status.date < status.date: latest_status = status return latest_Status 现在你可以在 Python 端使用 latest_status 来获取这本书的最新状态。 如果在取书时添加 prefetch
  • 属性对Django模型字段有效吗?(do properties work on django model fields?)
    问题 我认为最好的方法是用一些代码...我可以这样做吗? (编辑:答案:否) class MyModel(models.Model): foo = models.CharField(max_length = 20) bar = models.CharField(max_length = 20) def get_foo(self): if self.bar: return self.bar else: return self.foo def set_foo(self, input): self.foo = input foo = property(get_foo, set_foo) 还是我必须这样做: 是的,您必须这样做: class MyModel(models.Model): _foo = models.CharField(max_length = 20, db_column='foo') bar = models.CharField(max_length = 20) def get_foo(self): if self.bar: return self.bar else: return self._foo def set_foo(self, input): self._foo = input foo = property(get_foo, set_foo) 注意
  • Django - 在父管理员的 save_model() 中访问更改的 InlineAdmin 字段(Django - Access changed InlineAdmin fields within parent Admin's save_model())
    问题 如果之前已经解决过这个问题,请道歉。 由于我无法为此找到合适的解决方案,因此不得不询问。 当父管理员的 save_model() 中模型的内联管理字段发生更改时,我需要执行一个操作(一个 API 调用,告诉我的客户从他们的末端更新模型)。 模型.py class Student(models.Model) name = CharField() age = DateField() class Marks(models.Model) student = ForeignKey(Student) subject = CharField() marks = IntegerField() 管理文件 class MarksInline(admin.TabularInline): model = Marks form = MarksForm formset = MarksInlineFormSet class StudentAdmin(admin.ModelAdmin): form = StudentForm inlines = [MarksInline, ] 我可以通过检查StudentAdmin save_model()的form.changed_data和MarksInline模型的MarksInlineFormSet clean()方法来实现这一点。
  • Django什么时候查找外键的主键?(When does Django look up the primary key of foreign keys?)
    问题 我有两个简单的模型,一个代表电影,另一个代表电影的评级。 class Movie(models.Model): id = models.AutoField(primary_key=True) title = models.TextField() class Rating(models.Model): id = models.AutoField(primary_key=True) movie = models.ForeignKey(Movie) rating = models.FloatField() 我的期望是我将能够首先创建一个Movie和一个引用该电影的Review ,然后将它们提交到数据库中,只要我先提交了Movie以便给它一个主键供Review引用。 the_hobbit = Movie(title="The Hobbit") my_rating = Rating(movie=the_hobbit, rating=8.5) the_hobbit.save() my_rating.save() 令我惊讶的是,它仍然引发了一个IntegrityError抱怨我试图指定一个空外键,即使Movie已经提交并且现在有一个主键。 IntegrityError: null value in column "movie_id" violates not-null constraint
  • 我是否应该以任何方式避免在Django中进行多表(具体)继承?(Should I avoid multi-table (concrete) inheritance in Django by any means?)
    问题 许多经验丰富的开发人员建议不要使用Django多表继承,因为它的性能很差: Django陷阱:Django的核心贡献者Jacob Kaplan-Moss的具体继承。 从长远来看,在几乎每种情况下,抽象继承都是一种更好的方法。 我已经看到了不止几个站点在具体继承所带来的负担下被压垮,因此我强烈建议Django用户对任何具体继承的使用都抱有很大的怀疑态度。 Django的两个独家新闻,作者Daniel Greenfield(@pydanny) 作者和许多其他开发人员认为多表继承(有时也称为“具体继承”)是一件坏事。 强烈建议您不要使用它。 不惜一切代价,每个人都应该避免多表继承,因为它会增加混乱和大量开销。 代替多表继承,在模型之间使用显式的OneToOneFields和ForeignKeys,以便您可以控制遍历联接的时间。 但是如果没有多表继承,我将很难 另一个模型中的参考基础模型(必须使用GenericForeignKey或反向依赖); 获取基本模型的所有实例。 (随时添加更多) 那么Django中的这种继承有什么问题呢? 为什么显式的OneToOneFields更好? JOIN对性能有多大影响? 是否有任何基准可以表明性能差异? select_related()不允许我们控制何时调用JOIN吗? 自从这个问题变得过于广泛以来,我已经将具体示例移到了一个单独的问题上
  • Django REST Framework 序列化程序 - 访问现有的外键(Django REST Framework serializer - access existing foreign key)
    问题 我在我的应用程序中使用 Django Rest Framework,我需要创建包含外键的新模型实例。 这些引用另一个表中的现有对象,因此我不希望创建这些外部对象的新实例。 也无法通过自己的主键访问这些对象,因为该信息不提交(I需要在某些字段滤波器被包括在POST请求)。 我该怎么做呢? 这个问题似乎解决了同样的问题,尽管我不清楚接受的答案是否真的解决了这个问题。 假设我有两个模型Category和Item ,后者中有一个ForeignKey字段指定类别: class Category(models.Model): name = models.TextField() format = models.TextField() page = models.IntegerField(default=1) order = models.IntegerField(default=1) class Item(models.Model): username = models.TextField() title = models.TextField() category = models.ForeignKey('Category', null=True) data = JSONField(null=True, blank=True) POST请求的主体包含一个 JSON 负载,类别定义为指定格式
  • How to delete old image when update ImageField?(How to delete old image when update ImageField?)
    问题 我正在使用Django创建一个图片站点,我的模型中有一个ImageField,问题是当用户更新图像字段时,原始图像文件没有从硬盘上删除。 更新后如何删除旧图像? 回答1 您必须手动删除旧图像。 图像的绝对路径存储在your_image_field.path 。 因此,您将执行以下操作: os.remove(your_image_field.path) 但是,为方便起见,您可以使用关联的FieldFile对象,该对象可轻松访问基础文件,并提供一些便捷方法。 参见http://docs.djangoproject.com/en/dev/ref/models/fields/#filefield-and-fieldfile 回答2 使用django-cleanup pip install django-cleanup settings.py INSTALLED_APPS = ( ... 'django_cleanup', # should go after your apps ) 回答3 在模型中使用此自定义保存方法: def save(self, *args, **kwargs): try: this = MyModelName.objects.get(id=self.id) if this.MyImageFieldName != self.MyImageFieldName
  • Django如何从给定模型实例的自定义字段调用方法?(Django how to call a method from a custom field given a model instance?)
    问题 我有以下模型: class CustomField(models.CharField): def foo(self): return 'foo' class Test(models.Model): col1 = models.CharField(max_length=45) col2 = CustomField(max_length=45) 如果给我一个Test实例,如何从CustomField调用foo方法? 例如: >>> t = Test.objects.create(col1='bar', col2='blah') >>> t.col2 'blah' >>> t.col2.foo() # 'str' object has not attribute 'foo' 'foo' 当然,这会抛出: “str”对象没有属性“foo” 因为调用model_instance.column返回列的值,而不是一个实例column 。 但究竟是为什么呢? 似乎 Django 的 ORM 神奇地将字段类的实例转换为值。 我花了数小时挖掘源代码,但似乎无法找到转换发生的位置。 TLDR; 给定模型实例是否可以返回字段类的实例? 知道这在 Django 的源代码中发生在哪里吗? 我假设这发生在django/db/models/base.py ,但该文件有超过 1800 行代码,所以很难说。