如何用 TextInput 替换 Django ModelForm 中的 Choices 字段

德雷米特

我正在使用 Python 3.7.3 和 Django 2.0.13。

基本上我想在我的网站上显示一个表单,可以在其中输入用户(=下面模型定义中的参与者)。Django ModelForm 自动将其设置为选择字段并显示所有用户的下拉列表。我不想在下拉菜单中显示所有用户的列表,而是想要一个 TextInput 字段。

代码:

首先,来自models.py的相关部分:

class Invite(models.Model):
    game        = models.ForeignKey(Game, on_delete=models.CASCADE)

    host        = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "invites_as_host")
    participant = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "invites_as_participant")

    accepted = models.BooleanField(blank = True, default = False)
    declined = models.BooleanField(blank = True, default = False)

    date_created = models.DateTimeField(auto_now_add=True)
    date_edited  = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ["game", "host", "participant"]

表格.py:

class GameInviteNewForm(forms.ModelForm):
    class Meta:
        model = Invite
        fields = ["participant"]

我尝试的是像这样覆盖参与者输入字段:

class GameInviteNewForm(forms.ModelForm):

    participant = forms.CharField(
                label=_("User to invite"), 
                max_length=100,
                widget = forms.TextInput
            )

    class Meta:
        model = Invite
        fields = ["participant"]

views.py(如果相关;我认为它甚至不会达到“form_valid”,是吗?)

class GameInviteNewView(LoginRequiredMixin, UserIsLeaderMixin, FormView):
    form_class = GameInviteNewForm 

    template_name = "app/game/new_invite.html"

    pk_url_kwarg  = "game_id"


    def get_success_url(self):
        return reverse_lazy("app:game_invite", kwargs={
            "game_id": self.kwargs['game_id']
        })


    def form_valid(self, form):
        participant = form.save(commit=False)

        participant = User.objects.get(username=participant.name)
        host = User.objects.get(username=self.request.user.username)
        game = Game.objects.get(id=self.kwargs['game_id'])

        invite.participant_id = participant.id
        invite.host_id = host.id
        invite.game_id = game.id

        invite.save()

        return redirect(self.get_success_url())

这确实在网站上显示了一个 TextInput 字段,但是如果我输入用户名(“test”),我会收到一个错误:

Internal Server Error: /app/game/invite/7
Traceback (most recent call last):
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/contextlib.py", line 74, in inner
    return func(*args, **kwds)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/views/generic/base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/contrib/auth/mixins.py", line 109, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/views/generic/base.py", line 89, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/views/generic/edit.py", line 141, in post
    if form.is_valid():
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/forms/forms.py", line 179, in is_valid
    return self.is_bound and not self.errors
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/forms/forms.py", line 174, in errors
    self.full_clean()
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/forms/forms.py", line 378, in full_clean
    self._post_clean()
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/forms/models.py", line 396, in _post_clean
    self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/forms/models.py", line 60, in construct_instance
    f.save_form_data(instance, cleaned_data[f.name])
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 838, in save_form_data
    setattr(instance, self.name, data)
  File "/home/dremet/anaconda3/envs/django/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 197, in __set__
    self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "'test'": "Invite.participant" must be a "User" instance.

下拉列表在每个选项的“值”属性中都有用户 ID。现在,输入一个字符串。所以我对它不起作用并不感到惊讶,但我很惊讶错误消息说它必须是“用户”(而不是用户 ID)。我试图覆盖“clean()”方法并使用常规形式,但都没有成功。这应该如何正确处理?


解决方案:

正如答案中所指出的,我确实需要一个“clean_participant”方法,但是我在它周围包裹了一个 try-except 结构(并且我坚持使用 forms.py 更改覆盖参与者字段):

    def clean_participant(self):

        participant_string = self.cleaned_data['participant']

        try:
            participant = User.objects.get(username=participant_string)
        except User.DoesNotExist:
            raise forms.ValidationError("User does not exist.")

        return participant

纳菲斯·安瓦尔

您可以覆盖participant字段的clean 方法并从中返回用户实例。如果您使用选择字段,模型表单将自动执行此操作,因为表单将具有 id 来查找实例。因为您正在覆盖字段,所以您必须在清理过程中以某种方式自己找到相关实例。您可以通过为这样的参与者字段定义干净的方法来实现。

class GameInviteNewForm(forms.ModelForm):
    class Meta:
        model = Invite
        fields = ["participant"]

    def clean_participant(self):
        # you have to return a user instance from here some how use filtering logic you want
        participant = self.cleaned_data['participant']
        # just an example handle exceptions and other stuff
        return User.objects.get(username=participant)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Django modelform中隐藏字段?

来自分类Dev

在Django ModelForm中动态更改字段选择

来自分类Dev

在CreateView中设置Django ModelForm的字段值

来自分类Dev

在MongoDB聚合管道中,如何用数组字段替换root?

来自分类Dev

如何在Django ModelForm中设置基于用户的表单字段选择(使用django-allauth)

来自分类Dev

如何在Django ModelForm中设置基于用户的表单字段选择(使用django-allauth)

来自分类Dev

在Django2.1中提交后,如何在modelform中获取ckeditor字段值?

来自分类Dev

Django模型-在Choices字段中更改选项并迁移

来自分类Dev

如何在Django中为继承的模型属性创建通用的modelform字段验证器?

来自分类Dev

如何在Django中为继承的模型属性创建通用的modelform字段验证器?

来自分类Dev

如何在Django ModelForm Factory中呈现不可编辑的字段

来自分类Dev

如何在Django ModelForm中添加表单作为字段属性

来自分类Dev

无法在Django 1.4中的ModelForm中设置排除字段

来自分类Dev

Django 1.5 ModelForm中的“此字段不能为空”错误

来自分类Dev

Django:将ModelForm中的某些字段设为required = False

来自分类Dev

Django-访问模板中的modelform字段值

来自分类Dev

在Django 1.6中覆盖ModelForm字段错误消息

来自分类Dev

动态包含/排除Django ModelForm的Meta类中的字段

来自分类Dev

Django-验证modelform_factory中的禁用字段

来自分类Dev

在Django 1.6中覆盖ModelForm字段错误消息

来自分类Dev

在CreateView中为Django ModelForm设置字段的值

来自分类Dev

Django根据模型实例限制ModelForm中的ManyToMany字段的选项

来自分类Dev

验证 Django 2 中动态创建的 ModelForm 字段

来自分类Dev

如何在Django视图中访问ModelForm的字段

来自分类Dev

django modelform属性隐藏字段

来自分类Dev

Django中的ModelForm,如何获取maxlength属性

来自分类Dev

如何在Django ModelForm中显示选择

来自分类Dev

如何在 Django ModelForm 中获取实例

来自分类Dev

如何用自定义字段中的值替换Wordpress中的永久链接?

Related 相关文章

  1. 1

    如何在Django modelform中隐藏字段?

  2. 2

    在Django ModelForm中动态更改字段选择

  3. 3

    在CreateView中设置Django ModelForm的字段值

  4. 4

    在MongoDB聚合管道中,如何用数组字段替换root?

  5. 5

    如何在Django ModelForm中设置基于用户的表单字段选择(使用django-allauth)

  6. 6

    如何在Django ModelForm中设置基于用户的表单字段选择(使用django-allauth)

  7. 7

    在Django2.1中提交后,如何在modelform中获取ckeditor字段值?

  8. 8

    Django模型-在Choices字段中更改选项并迁移

  9. 9

    如何在Django中为继承的模型属性创建通用的modelform字段验证器?

  10. 10

    如何在Django中为继承的模型属性创建通用的modelform字段验证器?

  11. 11

    如何在Django ModelForm Factory中呈现不可编辑的字段

  12. 12

    如何在Django ModelForm中添加表单作为字段属性

  13. 13

    无法在Django 1.4中的ModelForm中设置排除字段

  14. 14

    Django 1.5 ModelForm中的“此字段不能为空”错误

  15. 15

    Django:将ModelForm中的某些字段设为required = False

  16. 16

    Django-访问模板中的modelform字段值

  17. 17

    在Django 1.6中覆盖ModelForm字段错误消息

  18. 18

    动态包含/排除Django ModelForm的Meta类中的字段

  19. 19

    Django-验证modelform_factory中的禁用字段

  20. 20

    在Django 1.6中覆盖ModelForm字段错误消息

  21. 21

    在CreateView中为Django ModelForm设置字段的值

  22. 22

    Django根据模型实例限制ModelForm中的ManyToMany字段的选项

  23. 23

    验证 Django 2 中动态创建的 ModelForm 字段

  24. 24

    如何在Django视图中访问ModelForm的字段

  25. 25

    django modelform属性隐藏字段

  26. 26

    Django中的ModelForm,如何获取maxlength属性

  27. 27

    如何在Django ModelForm中显示选择

  28. 28

    如何在 Django ModelForm 中获取实例

  29. 29

    如何用自定义字段中的值替换Wordpress中的永久链接?

热门标签

归档