【问题标题】:Problem with ManyToManyField in other model's forms using Bootstrap使用 Bootstrap 的其他模型形式中的 ManyToManyField 问题
【发布时间】:2019-12-18 14:27:06
【问题描述】:

我想在 Owners 表单中显示来自 ManyToManyField(我在 Homes 模型中)的可能选择。我有 Owners Homes 和自定义类 HomesOwners。在 Homes 中它是开箱即用的,我不知道如何让它在 Owners 中运行。

我正在使用带有 Bootstrap 4 和 Postgresql 的 Django 2.2.4。我基于 django-bookshelf 项目(也只是 Django 和 Bootstrap4)开始了我的项目。我不使用任何渲染。 django-bookshelf 项目中的评论提到了How to add bootstrap class to Django CreateView form fields in the template?,所以如果涉及到表单,我会坚持这一点。

我对 Python(对 Django 也是如此)和一般的 Web 技术还很陌生。我用谷歌搜索了十几个不同的问题/答案,但我找不到任何关于什么是什么以及如何在现实生活中使用它的很好的解释。他们中的大多数以基本用法结束。

我自己做了一些实验,但到目前为止没有成功......



这里是代码

我有两个模型 - Homes/models.pyOwners/models.py

Homes/models.py:

class Homes(models.Model):
   id = models.AutoField(primary_key=True)
   # other fields
   some_owners = models.ManyToManyField(Owners, through='HomesOwners', through_fields=('id_home', 'id_owner'), related_name='some_owners')
   # end of fields, some other code in the class like "class Meta" etc.

class HomesOwners(models.Model):
   id = models.AutoField(primary_key=True)
   id_home = models.ForeignKey(Homes, models.DO_NOTHING, db_column='id_home')
   id_owner = models.ForeignKey('owners.Owners', models.DO_NOTHING, db_column='id_owner')

Owners/models.py 没有任何特别之处,没有从我的 Homes/models.py 等导入。


和我的表格:

Homes/forms.py

class HomesForm(forms.ModelForm):
   def __init__(self, *args, **kwargs):
      super(HomesForm, self).__init__(*args, **kwargs)
      self.fields['some_field_from_homes_model'].widget.attrs = {'class': 'form-control '}
      #
      # --> no need self.fields for M2M, Django does the work
      #
      # but I tried also and have a --> Question 2
      # self.fields["some_owners"].widget = forms.widgets.CheckboxSelectMultiple()
      # self.fields["some_owners"].queryset = HomesOwners.objects.all()

没有任何代码作为 M2M 字段的 “self.fields”,Django 能够为我生成所有者列表。



问题 1

我想在我的 OwnersForms 中获取 Homes 的列表。

我不知道要添加什么。我假设我不能添加

# Owners/models.py
some_homes = models.ManyToManyField(Homes, through='HomesOwners', through_fields=('id_home', 'id_owner'), related_name='some_homes')

因为循环导入,对吗?

如何使用 self.fields 获取我的 Homes 列表? 我需要在代码中添加什么?



问题 2

当我添加了

# Homes/forms.py
self.fields["some_owners"].widget = forms.widgets.CheckboxSelectMultiple()
self.fields["some_owners"].queryset = HomesOwners.objects.all()

我明白了

<!-- html page -->
HomesOwners object (1)
HomesOwners object (2)
<!-- and so on... -->

如何只列出所有者? 如何过滤/排序它们,以便它们首先显示为没有连接到任何家庭的所有者?



问题 3

class HomesOwners(models.Model):
   id = models.AutoField(primary_key=True)
   id_home = models.ForeignKey(Homes, models.DO_NOTHING, db_column='id_home')
   id_owner = models.ForeignKey('owners.Owners', models.DO_NOTHING, db_column='id_owner')

def __str__(self):
   return pass #return something

我无法理解这一点。此类连接 HomesOwners。当我想到 Homes 时,我想返回 Owners,反之亦然。所以它应该根据我们使用的对象(家庭或所有者)返回不同的东西。我认为这与我的第二个问题有关:

HomesOwners object (1)

还有……

homes.html 我正在使用我的 M2M:

{% for owner in homes.homesowners_set.all %}
{{ owner.id_owner.id }}
{% endfor %}

我想写一些类似于我的 owners.html 的内容并列出房屋。这与我之前的问题有关,如果可能的话,我希望得到完整的答案。

编辑

根据给我的答案,我能够将 Homes 添加到 OwnerUpdate 视图。我有这样的看法: owners/views.py

# List View
class OwnersList(ListView):
    model = Owners

# Detail View
class OwnersView(DetailView):
    model = Owners

# Create View
class OwnersCreate(CreateView):
    model = Owners
    form_class = OwnersForm
    # Setting returning URL
    success_url = reverse_lazy('owners_list')

# Update View
class OwnersUpdate(UpdateView):
    model = Owners
    form_class = OwnersForm
    success_url = reverse_lazy('owners_list')

# Delete View
class OwnersDelete(DeleteView):
    model = Owners
    success_url = reverse_lazy('owners_list')

我需要进行哪些更改才能在 OwnersList 中显示他们拥有的房屋? 在 Homes DetailView 中,我可以显示所有者。我想对 Homes 的 DetailView 和 Homes ListView 做同样的事情。

【问题讨论】:

    标签: python django django-models bootstrap-4 django-forms


    【解决方案1】:

    我真的不明白你的要求,
    但如果我正确理解您的问题,
    我假设您想将 Homes 列表(不是 HomesOwners 列表)添加到您的 Owners 表单中,对吧?

    您可以像这样在表单中添加额外的字段:

    class OwnersForm(ModelForm):
        # notice the queryset is 'Homes' not 'HomesOwners'
        homes = forms.ModelMultipleChoiceField(queryset=Homes.objects.all(), widget=forms.CheckboxSelectMultiple)
    
        class Meta:
            model = Owners
            fields = ('homes', 'your_other_fields',)
    
        # then you can access in init function too if you want
        def __init__(self, *args, **kwargs):
            super(OwnersForm, self).__init__(*args, **kwargs)
            self.fields['homes'].required = False
    

    然后,由于它使用 CheckboxSelectMultiple 小部件,您可以像这样在 html 模板中对其进行迭代:

    {% for key, value in your_form.homes.field.choices %} <!-- notice '.field.'-->
    {{ key }} = {{ value }}
    {% endfor %}
    

    您可能还需要为您的表单创建自定义保存。


    对于你的问题 3,这不是关于形式的吗?
    如果您想展示 HomesOwners,您已经做对了。

    {% for owner in homes.homesowners_set.all %}
    {{ owner.id_owner.id }}
    {% endfor %}
    

    但如果 homes 只是 1 个对象,它将起作用。
    如果 homes 是一个查询集,您必须先对其进行迭代

    {% for home in homes %}
        {% for owner in home.homesowners_set.all %}
        {{ owner.id_owner.id }}
        {% endfor %}
    {% endfor %}
    

    抱歉,如果我误解了您的问题,
    也许您也可以提供您的views.py,以便我或其他人可以更具体地帮助您

    【讨论】:

    • 我刚玩了第一部分,不得不修改一些东西,但我认为主要的事情是有效的。非常感谢您的意见!
    • 我编辑了我的帖子,又添加了一个问题。你认为你也可以帮助我吗?
    • 您可以在您的视图中覆盖get_context_data 方法。看到这个docs
    猜你喜欢
    • 2020-07-03
    • 2019-05-23
    • 2011-02-19
    • 2019-08-10
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多