python - 如何在 Django CreateView 中创建对象后添加指令?
问题描述
在基于通用类的 CreateView 上,我想执行一条指令,该指令从与当前创建的对象相关的另一个模型创建新对象。
示例:
Collection
是与 3 个不同Element
对象相关的模型。当我创建一个与 a和 aMyCollection
相关的对象时,也必须创建3 个对象并与新创建的对象相关。每个与 相关的一个。Collection
User
MyElement
MyCollection
Element
Collection
# models.py
from django.contrib.auth.models import User
from django.db import models
class Collection(models.Model):
# attributes and methods...
class Element(models.Model):
collection = models.ForeignKey(Collection, # more arguments...)
# more attributes and methods
class MyCollection(models.Model):
user = models.ForeignKey(User, # more arguments...)
collection = = models.ForeignKey(Collection, # more arguments...)
# more attributes and methods
def get_absolute_url(self):
reverse(# some url with the object pk)
class MyElement(models.Model):
element = models.ForeignKey(Element, # more arguments...)
my_collection = models.ForeignKey(MyCollection, # more arguments...)
# more attributes and methods
我正在使用来自 Django 的通用 CreateView,经过一些研究,我发现可以通过覆盖 get_success_url() 方法在 CreateView 中执行其他操作。
在我的示例中,我做了类似的事情:
# views.py
from django.views.generic import CreateView
from .utils import create_myelements_for_mycollection
class MyCollectionCreateView(CreateView):
model = MyCollection
# more attributes and methods...
def get_success_url(self):
create_myelements_for_mycollection(self.get_object()) # Here is where the bug occurs, works fine without this line
return super().get_success_url()
# utils.py
from .models import Collection, Element, MyCollection, MyElement
def create_myelements_for_mycollection(my_collection):
for element in my_collection.collection.elements_set.all():
MyElement.objects.create(
element=element,
my_collection=my_collection,
)
# urls.py
from django.urls import re_path
from . import views
urlpatterns = [
re_path(
r"^myelement/l/$",
views.MyElementListView.as_view(),
),
re_path(
r"^myelement/r/(?P<pk>[0-9]+)/$",
views.MyElementDetailView.as_view(),
),
re_path(
r"^myelement/c/(?P<element_pk>\d+)/$",
views.MyElementCreateView.as_view(),
),
re_path(
r"^mycollection/l/$",
views.MyCollectionListView.as_view(),
),
re_path(
r"^mycollection/r/(?P<pk>[0-9]+)/$",
views.MyCollectionDetailView.as_view(),
),
re_path(
r"^mycollection/c/(?P<collection_pk>\d+)/$",
views.MyCollectionCreateView.as_view(),
),
]
当我创建一个新MyCollection
对象时,所有对象都MyElements
在数据库中成功创建,但出现此错误:
AttributeError:必须使用 URLconf 中的对象 pk 或 slug 调用通用详细视图 MyCollectionCreateView。
我不明白为什么。
我的 CreateView url 没有任何 pk,因为当您创建新对象时,它还没有 pk。还有,MyCollection
有自己的get_absolute_url
。没有那个具体的指示,我工作得很好。
有人可以解释一下导致错误的原因吗?在创建对象后是否有更好的方法来执行这样的指令?
谢谢您的帮助。
FYI:
Django 3.1
Pyhton 3.8
编辑
我尝试改用 post_save 信号(实际上写起来更干净),但我遇到了完全相同的错误。
# models.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from .utils import create_myelements_for_mycollection
# ...models
@receiver(post_save, sender=MyCollection)
def create_myelements_for_mycollection(sender, instance, **kwargs):
if instance is created: # ? (Didn't look at how to write this condition in a signal yet)
create_myelements_for_mycollection(my_collection)
AttributeError:必须使用 URLconf 中的对象 pk 或 slug 调用通用详细视图 MyCollectionCreateView。
编辑 2
通过从类中删除get_absolute_url()
覆盖MyCollectionCreateView
,它实际上可以工作。这很好,但我仍然想知道问题是什么。如果这解决了问题,可能我没有看到一些愚蠢的东西。
# models.py
# ... previous code
class MyCollectionCreateView(CreateView):
model = MyCollection
# more attributes and methods...
# Removing this solved the issue
# def get_success_url(self):
# create_myelements_for_mycollection(self.get_object())
#
# return super().get_success_url()
# more code ...
解决方案
get_absolute_url()
在为模型创建新实例时使用,因为当创建新帖子或创建新实例时,django 必须知道去哪里。
从错误
AttributeError:必须使用 URLconf 中的对象 pk 或 slug 调用通用详细视图 MyCollectionCreateView。
它告诉您必须使用 aobject pk
或 a调用它slug
,因此您对 URL 的构造是问题所在。我不确定该方法是否create_myelements_for_mycollection()
满足这种需求。
理想情况下,您需要的是类似的东西,例如
def get_absolute_url(self):
return f"/mycollection/{self.slug}/"
生成URL
上述模式中的,例如在锚标记中使用。
推荐阅读
- xpath - 使用 XPath 将参数传递到报表中的表
- javascript - XML 应用程序:时间字符串不起作用
- reactjs - 无法在反应组件中动态创建元素
- extjs - EXTJS 将行添加到 .insert() 上的容器顶部
- visual-studio-2012 - 无法删除重命名的文件夹
- javascript - NUXT 中间件中未定义 Vuex 存储
- java - Apache POI 3.14 将 SXSSF 写入 ServletResponse OutputStream 正在破坏工作簿 JSF
- javascript - 将缩放行为添加到自定义地图点
- asp.net-mvc - ASP.NET MVC 在 URL 路由之外指定类别/路径
- vb.net - 从表格中动态创建的单选按钮获取文本