关于python:在Django中,如何从单个表单字段填充泛型关系?

In Django, how to populate a generic relation from a single form field?

在我们的应用程序中,我们有一个A模型,它有一个通用关系字段,因为它可能与两个模型(BC中的任何一个模型的实例相关。

在填充非通用ForeignKey字段时,可以使用ModelChoiceField。我们的问题是我们找不到一个多元素的schoicefield,它的选择将由BC上的查询集填充。

如何通过尽可能多地重用现有的django代码来解决这个问题?


你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class YourForm(forms.ModelForm):
    your_field = forms.ChoiceField()

    def __init__(self, *args, **kwargs):
        super(YourForm, self).__init__(*args, **kwargs)
        your_generic_relations_objects = list(FirtsModel.object.all()) + list(SecondModel.objects.all())  # and etc
        object_choices = []
        for obj in your_generic_relations_objects:
            type_id = ContentType.objects.get_for_model(obj.__class__).id
            obj_id = obj.id
            form_value = 'type:%s-id:%s' % (type_id, obj_id)
            display_text = str(obj)
            object_choices.append([form_value, display_text])
        self.fields['your_field'] = forms.ChoiceField(choices=object_choices)

    class Meta:
        model = YourModel
        fields = [
            'your_field'  # and others
        ]

    def save(self, *args, **kwargs):
        object_string = self.cleaned_data['your_field']
        matches = re.match("type:(\d+)-id:(\d+)", object_string).groups()
        content_type_id = matches[0]
        object_id = matches[1]
        content_type = ContentType.objects.get(id=content_type_id)
        self.instance.object_id = object_id
        self.instance.content_type = content_type
        return super(YourForm, self).save()