javascript - Django Rest Framework - 获取相关的 FK 对象以在模板中使用;POST现在不起作用?
问题描述
我已经建立了一个表格并使用了 Vue 前端和 DRF 后端。它是一种用于添加(创建)新模型的表单 - 并具有相关模型的下拉列表,这些模型是正在创建的模型的 FK。
我需要访问所选 FK 项目的属性。
我的序列化程序如下所示:
class SubdomainSerializer(serializers.ModelSerializer):
class Meta:
model = Subdomain
fields = [
"id",
"domain",
"short_description",
"long_description",
"character_code",
]
# def get_absolute_url(self, obj):
# return obj.get_absolute_url()
class EvidenceSerializer(serializers.ModelSerializer):
created_by = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
updated_by = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
absolute_url = serializers.SerializerMethodField()
created_by_name = serializers.SerializerMethodField()
updated_by_name = serializers.SerializerMethodField()
class Meta:
model = Evidence
fields = "__all__"
该表单用于创建一个新的“证据”项,“子域”是表单上包含所有相关子域的下拉菜单。
模型如下所示:
class Subdomain(CreateUpdateMixin):
domain = models.ForeignKey(Domain, on_delete=models.PROTECT)
short_description = models.CharField(max_length=100)
long_description = models.CharField(max_length=250)
character_code = models.CharField(max_length=5)
class Evidence(CreateUpdateMixin, CreateUpdateUserMixin, SoftDeletionModel):
subdomain = models.ForeignKey(Subdomain, on_delete=models.PROTECT)
evaluation = models.ForeignKey(
Evaluation, related_name="evidences", on_delete=models.PROTECT
)
published = models.BooleanField(default=False)
comments = models.CharField(max_length=500)
在我的表单中,我只想在用户从下拉列表中选择它时包含short_description
每个subdomain
- 我可能也想使用long_description
。
这是我呈现下拉列表的表单中的位:
<div class="form-group col-sm-4">
<label class="" for="subdomain">Subdomain</label>
<select name="subdomain" id="subdomain" class="form-control" v-model="element.subdomain">
<option v-for="choice in subdomains" :value="choice.id" >{{ choice.character_code }}</option>
</select>
</div>
<div class="small" v-if="element.subdomain">
<!-- THIS IS WHERE I WOULD LIKE TO DISPLAY THE SHORT DESCRIPTION FOR THE CHOICE IN THE DROPDOWN -->
{{ choice.short_description }}
</div>
当我发布时,表单数据看起来像这样:
evaluation: 2037
subdomain: 448
comments: Test comments to add to the subdomain
published: true
csrfmiddlewaretoken: 382796ryfuasiodfgyhakljyht37yaisdfaslk3r
我尝试过的东西-其中一些用于显示目的,但似乎破坏了表单/POST:
添加
depth=1
到 的 Meta 中EvidenceSerializer
,这有效但使表单不再正确提交。我认为这是因为它想要整个子域而不仅仅是 ID?我无法让它工作 - 子域总是抛出错误。将以下内容添加到 my
EvidenceSerializer
中,这似乎再次破坏了 POST 操作,这将导致子域下拉列表引发错误。
subdomain = SubdomainSerializer(read_only=True)
使用下拉列表上方的这两种方法都无法识别subdomain_id
被选中的对象,并且最终都会在幕后引发此错误:
Cannot insert the value NULL into column 'subdomain_id', table 'local_app.dbo.myapp_evidence'; column does not allow nulls. INSERT fails.
任何关于如何进行的建议都会很棒。
TLDR;需要能够使用 DRF 访问 FK 关系上的属性以获取下拉列表,并能够在表单中提交该项目。
解决方案
感谢@bdbd 为我指明了正确的方向。
对于任何好奇的人,我使用这些链接解决了它 - 结果我需要稍微更改我的序列化程序:
class SubdomainSerializer(serializers.ModelSerializer):
class Meta:
model = Subdomain
fields = [
"id",
"domain",
"short_description",
"long_description",
"character_code",
]
class EvidenceSerializer(serializers.ModelSerializer):
created_by = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
updated_by = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
absolute_url = serializers.SerializerMethodField()
created_by_name = serializers.SerializerMethodField()
updated_by_name = serializers.SerializerMethodField()
# add the 'subdomain' as read only - but with all the attributes
subdomain = SubdomainSerializer(read_only=True)
# add the 'subdomain_id' as a PrimaryKeyRelatedField with the source being the subdomain
subdomain_id = serializers.PrimaryKeyRelatedField(
queryset=Subdomain.objects.all(), source="subdomain"
)
class Meta:
model = Evidence
fields = "__all__"
然后我稍微更新了 HTML:
<div class="form-group col-sm-4">
<label class="" for="subdomain_id">Subdomain</label>
<select name="subdomain_id" id="subdomain" class="form-control" v-model="element.subdomain">
<option v-for="choice in subdomains" :value="choice" >{{ choice.character_code }}</option>
</select>
</div>
<div class="small" v-if="element.subdomain_id">
{{ element.subdomain.short_description }}
</div>
然后在 ajax 调用中,我只需subdomain_id
将subdomain.id
data: {
evaluation : evaluationId,
subdomain_id : vm.element.subdomain.id,
comments : vm.element.comments,
published: vm.element.published,
csrfmiddlewaretoken: vm.sharedStore.state.csrftoken,
},
推荐阅读
- post - 为什么我的 Python 发布请求返回 400 错误?
- php - 在没有现在保存价格的情况下更改 woocommerce 产品中的 html
- angular - 如何在 Ng 字段中填充 localstorage 键值
- javascript - 在 NodeJS (Express) 中使用 Promise.all 找不到集合时出现 404 页面
- spacy - 使用 ELMo/BERT 进行预训练的参考文本
- php - 我想将我的提交数据显示到输入表单中
- heroku - Heroku php buildpack 在 IBM Cloud Foundry 上运行缓慢
- c - 在这种情况下 [i] 变量的含义是什么?
- django - 'if' 语句中的多个 django 'with' 语句
- python-3.x - Pandas:基于多列对数据框进行排序