django - Django REST Serializers - 在创建新对象时传递一个值
问题描述
使用 Django REST 序列化程序创建对象时,我在传递参数时遇到问题。
模型.py
class Project(models.Model):
name = models.CharField(max_length=200, unique=False)
description = models.TextField()
...
class Hypothesis(models.Model):
hypothesis = models.CharField(max_length=200, unique=False)
project = models.ManyToManyField(Project)
test_conducted = models.ManyToManyField('Interview', through='HypothesesFeedback')
...
序列化程序.py
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = ['name','description','company_name']
def __init__(self, *args, **kwargs):
super(ProjectSerializer, self).__init__(*args, **kwargs)
class HypothesisSerializer(serializers.ModelSerializer):
class Meta:
model = Hypothesis
fields = ['hypothesis','area','details', 'project']
def get_alternate_name(self, obj):
project = self.context["project_id"]
视图.py
class ProjectRestCreate(LoginRequiredMixin, generics.ListCreateAPIView):
queryset = Project.objects.all()
serializer_class = ProjectSerializer
...
class HypothesisRestCreate(LoginRequiredMixin, generics.ListCreateAPIView):
queryset = Hypothesis.objects.all()
serializer_class = HypothesisSerializer
def get_serializer_context(self):
context = super().get_serializer_context()
context["project_id"] = 8 #self.kwargs['project_id']
return context
...
在为类假设创建新对象时,我目前无法默认项目 ID。在上面的示例中,我只是出于测试目的硬编码一个值,但我需要达到的是,当我从给定的项目页面创建一个新假设时,项目会自动填充,而不是用户拥有手动选择它。
使用 Django,而不是 Django REST,我可以使用下面的代码来实现:
class HypothesisCreate(generic.CreateView):
model = Hypothesis
form_class = HypothesisForm
template_name = 'new_hypothesis.html'
def form_valid(self, form):
obj = form.save()
project = form.data['project']
p = Project.objects.filter(id=project)
obj.project.set(p)
return super(HypothesisCreate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(HypothesisCreate, self).get_context_data(**kwargs)
context['p_id'] = self.kwargs['project']
return context
def get_success_url(self, **kwargs):
return reverse('project_detail', kwargs={'pk': self.kwargs['project']})
关于如何使用 Django REST 序列化程序达到相同的任何想法?
编辑#1
模型.py
class Project(models.Model):
name = models.CharField(max_length=200, unique=False)
description = models.TextField()
...
class Hypothesis(models.Model):
hypothesis = models.CharField(max_length=200, unique=False)
project = models.ForeignKey(Project, on_delete= models.CASCADE)
test_conducted = models.ManyToManyField('Interview', through='HypothesesFeedback')
...
使用 Django 而不是 Django REST,我在创建新假设时使用 get_context_data 实现了项目的默认设置:
VIEW:
class HypothesisCreate(generic.CreateView):
model = Hypothesis
form_class = HypothesisForm
template_name = 'new_hypothesis.html'
def form_valid(self, form):
obj = form.save()
project = form.data['project']
p = Project.objects.filter(id=project)
obj.project.set(p)
return super(HypothesisCreate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(HypothesisCreate, self).get_context_data(**kwargs)
context['p_id'] = self.kwargs['project']
return context
def get_success_url(self, **kwargs):
return reverse('project_detail', kwargs={'pk': self.kwargs['project']})
FORM:
class HypothesisForm(ModelForm):
class Meta:
model = Hypothesis
fields = ['hypothesis','area','details']
def __init__(self, *args, **kwargs):
super(HypothesisForm, self).__init__(*args, **kwargs)
self.fields["project"] = forms.CharField(widget=forms.HiddenInput())
我尝试对序列化程序做同样的事情,但没有成功。
VIEW:
class HypothesisRestCreate(LoginRequiredMixin, generics.ListCreateAPIView):
queryset = Hypothesis.objects.all()
serializer_class = HypothesisSerializer
def get_serializer_context(self):
context = super().get_serializer_context()
context["project_id"] = 8 #self.kwargs['project_id']
return context
SERIALIZER:
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = ['name','description','company_name']
def __init__(self, *args, **kwargs):
super(ProjectSerializer, self).__init__(*args, **kwargs)
class HypothesisSerializer(serializers.ModelSerializer):
class Meta:
model = Hypothesis
fields = ['hypothesis','area','details', 'project'] #
def get_alternate_name(self, obj):
project = self.context["project_id"]
知道我应该做些什么不同吗?
解决方案
修改HypothesisRestCreate
如下
class HypothesisRestCreate(LoginRequiredMixin, generics.ListCreateAPIView):
queryset = Hypothesis.objects.all()
serializer_class = HypothesisSerializer
def create(self, request, *args, **kwargs):
request.data['project'] = self.kwargs['project_id']
return super(HypothesisRestCreate, self).create(request, *args, **kwargs)
# def get_serializer_context(self): -- dont need for this purpose
HypothesisSerializer
如下_
class HypothesisSerializer(serializers.ModelSerializer):
class Meta:
model = Hypothesis
fields = ['hypothesis','area','details', 'project']
# def get_alternate_name(self, obj): --dont need for this purpose
推荐阅读
- junit5 - Junit 5:如何为参数化测试提供名称
- javascript - 生产模式下的 Nuxt.js 安全性
- azure-cognitive-search - 在嵌套 json 中搜索(Azure 搜索)
- mongodb - 如何创建 Spring 数据聚合查询
- qt - 在不破坏绑定的情况下更改属性值以支持双向绑定
- php - PHP 注意:未初始化的字符串偏移量
- php - 如何在 Opencart 的主类别页面上显示子类别图像?
- python - 从 CSV 检索数据并将其保存到列表中时遇到问题
- javascript - addEventListener 为空
- rust - 如何修复 Rust 中的“无法编译 `user32-sys”错误