0

他のモデルへの外部キーを持つモデルを定義しました。models.pyに次のものがあるように:

class Appelation(models.Model):

    appelation = models.CharField(max_length=100,
                              verbose_name=_('Appelation'),
                              validators=[non_numeric],
                              blank=True,
                              unique=True
                             )


class Wine(models.Model):
    appelation = models.ForeignKey(ForeignKeyModel, null=True, blank=True, verbose_name=_('Appelation'))

フォーム.py

class WineForm(ModelForm):

    class Meta: 
        model = Wine

    appelation= CharField(widget=TextInput)

ビュー.py

class WineCreateView(WineActionMixin, LoginRequiredMixin, CreateView):

model = Wine
form_class = WineForm
action = 'created'

def post(self, *args, **kwargs):
    self.request.POST = self.request.POST.copy()  # makes the request mutable

    appelationForm = modelform_factory(Appelation, fields=('appelation',))

    form_dict = {
        'appelation': appelationForm
    }
    for k, modelForm in form_dict.iteritems():
        model_class = modelForm.Meta.model
        log.debug('current model_class is: %s' % model_class)
        log.debug('request is %s' % self.request.POST[k])
        try:
            obj = model_class.objects.get( **{k: self.request.POST[k]} )
            log.debug("object exists. %s pk from post request %s " % (model_class,obj.pk))
            self.request.POST[k] = obj.id
        except ObjectDoesNotExist as e:
            log.error('Exception %s' % e)
            f = modelForm(self.request.POST)            
            log.debug('errors %s' % f.errors)
            if f.is_valid():
                model_instance = f.save()
                self.request.POST[k] = model_instance.pk

    return super(WineCreateView,self).post(self.request, *args, **kwargs)

基本的に、ビュー コードが行うことは、渡したものが存在しない場合、新しい Appelation モデル インスタンス (Wine の fk) を作成しようとすることです。入力として文字列ではなく pk が必要なため、フィールドに pk を返します。

私は、foreignKey 入力を検証するために適用する必要があるカスタム バリデーターをいくつか持っているため、apperationForm を作成したいと考えています。

私が今見ている制限は、 apperationForm からの検証エラーをメインフォームのものに添付して、通常foreignKeyフィールドからのものの代わりに表示する方法がわからないことです.

完全なサンプル コードを表示するには:

https://github.com/quantumlicht/django-wine/blob/master/project/corewine/models.py https://github.com/quantumlicht/django-wine/blob/master/project/corewine/forms.py https://github.com/quantumlicht/django-wine/blob/master/project/corewine/views.py

4

1 に答える 1

3

あなたがすべきことは、基準、つまり既存の Appelation id または新しい Appelation 名のいずれかに従って入力を包括的に検証し、適切なエラーを発生させるclean_appelationメソッドを に記述することです。WineForm次に、ビューで、フォーム データが有効であり、機能すると見なすことができます。これにより、次のことから始めることができます。

class WineForm(ModelForm):
    ...
    appelation= CharField(widget=TextInput)
    def clean_appelation(self):
        data = self.cleaned_data['appelation']
        if data.isdigit():
             # assume it's an id, and validate as such
             if not Appelation.objects.filter(pk=data):
                 raise forms.ValidationError('Invalid Appelation id')
        else:
             # assume it's a name
             if ...:
                 raise forms.ValidationError('Invalid Appelation name')
        return data
于 2013-11-04T02:14:19.250 に答える