首页 > 解决方案 > 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"]

知道我应该做些什么不同吗?

标签: djangodjango-rest-frameworkdjango-viewsdjango-serializer

解决方案


修改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

推荐阅读