使用Bootstrap的其他模型形式的ManyToManyField问题

时间:2019-08-11 21:53:23

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

我想在“所有者”表单中显示ManyToManyField(在Homes模型中具有此选项)的可能选择。我有所有者<-Many2Many->房屋,其中包含自定义类HomesOwners。在Homes中,它可以直接使用,我不知道如何在Owners中使用它。

我正在将Django 2.2.4与Bootstrap 4和Postgresql一起使用。我基于django-bookshelf项目(也只有Django和Bootstrap4)启动了我的项目。我不使用任何渲染。 django-bookshelf项目中的注释提到了How to add bootstrap class to Django CreateView form fields in the template?,因此如果涉及到表单,我会坚持下去。

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

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



这是代码

我有两个模型- Homes / models.py Owners / 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 中获得房屋的列表。

我不知道要添加什么。我认为我无法添加

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

因为是循环进口,对吗?

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



问题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 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进行同样的操作。

1 个答案:

答案 0 :(得分:0)

我并没有真正满足您的要求,
但是如果我正确理解了您的问题,
我假设您想将“房屋”列表(而不是“房屋所有者”列表)添加到“所有者”表单中,对吧?

您可以像这样在表单中添加其他字段:

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个问题与表格无关吗?
如果您想显示房屋所有者,那么您已经做对了。

{% 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,所以我或其他人可以帮助您更具体