#django #django-rest-framework #django-views #django-serializer
#django #django-rest-framework #django-представления #django-сериализатор
Вопрос:
У меня возникают проблемы с передачей аргумента при создании объекта с помощью сериализаторов Django REST.
models.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')
...
serializers.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"]
views.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
...
В настоящее время я не могу использовать идентификатор проекта по умолчанию при создании нового объекта для гипотезы класса. В приведенном выше примере я жестко кодирую значение только для целей тестирования, но мне нужно достичь того, что когда я создаю новую гипотезу, начиная с заданной страницы проекта, проект заполняется автоматически, а не пользователю приходится выбирать его вручную.
Используя 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?
EDIT #1
models.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')
...
using Django rather than Django REST, I achieve the defaulting of the project when creating a new hypothesis, using 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"]
есть идеи, что мне делать по-другому?
Комментарии:
1. почему
ManyToManyField
? каждая гипотеза может иметь несколько проектов, но дозировать любую проектную работу по многим гипотезам?2. для каждого проекта существует множество гипотез, которые необходимо проверить. На самом деле, предполагается, что каждая гипотеза связана только с одним проектом
3. затем используйте
Foraignkey
вместо этого.4. вы правы, спасибо за подсказку! Знаете ли вы также, как передать идентификатор проекта в качестве параметра в сериализаторе, чтобы при создании новой гипотезы из проекта N значение N автоматически присваивалось системой, а не пользователю приходилось выбирать его вручную?
5. задайте этот конкретный вопрос подробно с измененным кодом и укажите вашу точную проблему. поместите его ссылку здесь.
Ответ №1:
Измените 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