[Django] ModelChoiceField에서 동적으로 만든 옵션이 Model object가 될 때의 조치

12660 단어 장고

현상



Model에서 Form으로 선택 사항을 추가하려면 ModelChoiceField를 사용하지만,
선택사항이 Object가 되어 버릴 때의 대처법.
현상은 이런 느낌.


※유저 프로필을 작성하는 폼에, 국적의 폼이 있는 이미지.

이 시점의 코드



country/models.py
from django.db import models

class country(models.Model):
  name = models.CharField(max_length=100)

  class Meta:
    db_table = 'country'

user/profile/views.py
from django.shortcuts import render
from django.views.generic import FormView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from .forms import ProfileCreateForm
from country.models import Country

class ProfileCreateView(LoginRequiredMixin, FormView):
    form_class = ProfileCreateForm
    template_name = 'user/profile/create.html'
    success_url = reverse_lazy('user:dashboard')

    def get(self, request, **kwargs):
        form = ProfileCreateForm()
        form.fields['country'].queryset = Country.objects.all()
        datas = {'form': form}
        return render(self.request, self.template_name, datas)

user/profile/forms.py
from django import forms
from user.models import UserProfile
from country.models import Country

class ProfileCreateForm(forms.ModelForm):
    country = forms.ModelChoiceField(queryset=Country.objects.all(), empty_label='Select your Country')

    class Meta:
        model = UserProfile
        fields = ('name', 'country')

template/user/profile/create.html
{{form.country}}

대처법



ModelChoiceField의 label_from_instance()를 재정의합니다.

country/forms.py
from django import forms

class CustomModelChoiceField(forms.ModelChoiceField):
    def label_from_instance(self, obj):
        return obj.name

user/profile/forms.py
from django import forms
from user.models import UserProfile
from country.models import Country
from country.forms import CustomModelChoiceField

class ProfileCreateForm(forms.ModelForm):
    country = CustomModelChoiceField(queryset=Country.objects.all(), empty_label='Select your Country')

    class Meta:
        model = UserProfile
        fields = ('name', 'country')



DB 저장시 Model 객체가 될 때의 대응



user/profile/views.py
from django.shortcuts import render
from django.views.generic import FormView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from .forms import ProfileCreateForm
from country.models import Country

class ProfileCreateView(LoginRequiredMixin, FormView):
    form_class = ProfileCreateForm
    template_name = 'user/profile/create.html'
    success_url = reverse_lazy('user:dashboard')

    def get(self, request, **kwargs):
        form = ProfileCreateForm()
        form.fields['country'].queryset = Country.objects.all()
        datas = {'form': form}
        return render(self.request, self.template_name, datas)

    def form_valid(self, form):
        profile = form.save(commit=False)
        profile.country = self.request.POST['country']  # ここ
        profile.save()
        return super().form_valid(form)

참고



ModelChoiceField(영어)

좋은 웹페이지 즐겨찾기