1
class Advert(models.Model):
    location_relation = models.ForeignKey("administrative_division.Towns", to_field='name_unique')


class Towns(models.Model):
    name = models.CharField(max_length=128)
    slug = models.SlugField()

    voivodship = models.ForeignKey("Voivodships", to_field='voivodship_identifier')
    county = models.ForeignKey("Counties")

    name_unique=models.CharField(max_length=255, unique=True)
    town_unique=models.BooleanField()

    def __unicode__(self):
        return "%s. %s"% (self.id, self.name) 



class AdvertForm(ModelForm):

    category = CustomTreeNodeChoiceField(queryset=Category.objects.filter(parent__isnull=False), empty_label="Wybierz kategorię", label="Kategoria")

    class Meta:
        model = Advert
        exclude = ('ip', 'user')
        widgets = {
            'location_relation': TextInput
        }

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(AdvertForm, self).__init__(*args, **kwargs)

    def clean_location_relation(self):
        from string import capitalize
        from django import forms
        from administrative_division.models import Towns

        cleaned_data = self.cleaned_data['location_relation']
        try:
            cleaned_data = Towns.objects.get(name_unique=capitalize(cleaned_data.name_unique))
        except:
            raise forms.ValidationError("Such city does not exist")

        return cleaned_data

我使用文本输入表单字段而不是选择字段。所以我需要手动提供唯一的名称。

我需要将提供的字符串大写到名为 location_relation 的字段中。我尝试了不同的选项,例如在模型中使用清洁方法,现在我尝试以模型形式进行清洁。

我现在真的不知道该怎么做。

请给我一些提示或解决此问题的方法:)

4

1 回答 1

0

我只是做了这样的事情;您应该子类化ModelChoiceField并修改其prepare_valueclean方法以使用非整数输入(FK -ModelChoiceField 需要)。

在我的例子中,它是一个预先输入的外键文本字段,如果它不存在则创建新条目(例如对标签有用)。

class MyModelChoiceField(forms.ModelChoiceField):
    def __init__(self, *args, **kwargs):
        self.widget = kwargs.pop('widget', forms.TextInput)
        super(MyModelChoiceField, self).__init__(*args, **kwargs)

    def prepare_value(self, value):
        # return value from original value, a PK.
        value = super(MyModelChoiceField, self).prepare_value(value)
        if not value:
            return value

        try:
            return self.queryset.model.objects.get(id=value).name
        except self.queryset.model.DoesNotExist:
            return ''

    def clean(self, value):
        # return instance from text input string
        if not value and not self.required:
            return None
        elif not value:
            raise forms.ValidationError("%s is required" % (self.queryset.model._meta.verbose_name,))
        try:
            return self.queryset.model.objects.filter(my_field=value).get()
        except self.queryset.model.DoesNotExist:
            raise forms.ValidationError("%s is not a valid option" % (self.queryset.model._meta.verbose_name,))


class MyForm(forms.ModelForm):
    # ...
    my_field = MyModelChoiceField(queryset=Foo, etc.)

结合自定义小部件,我现在可以通过几行代码将它用于任何 FK 字段,并自动包含我的 typeahead JS。我爱django!

于 2012-08-19T16:19:14.660 回答