Django 嵌套管理员

Django Nested admin

这是我的代码:

models.py

from django.db import models
class Country(models.Model):
    country_name = models.CharField(max_length = 20, default = '', )
    country_other_details = models.CharField(max_length = 100, default = '', null = True)
    class Meta:
        verbose_name_plural = "Countries"
    def __str__(self):
        return self.country_name

class State(models.Model):
    in_country = models.ForeignKey(Country, related_name='in_country',on_delete=models.DO_NOTHING)
    state_name = models.CharField(max_length = 20, default = '')
    state_other_details = models.CharField(max_length=100, default = '', null = True)
    def __str__(self):
        return self.state_name

class City(models.Model):
    in_state = models.ForeignKey(State, related_name='in_state',on_delete=models.DO_NOTHING)
    city_name = models.CharField(max_length = 20, default = '')
    city_other_details = models.CharField(max_length = 100, null = True)

    class Meta:
        verbose_name_plural = "Cities"

    def __str__(self):
        return self.city_name

forms.py

from django.forms.models import inlineformset_factory
from django.forms.models import BaseInlineFormSet

from .models import Country, State, City

from django.forms.models import BaseInlineFormSet, inlineformset_factory
from django.utils.translation import ugettext_lazy as _

# from publishing.utils.forms import is_empty_form, is_form_persisted

CityFormset = inlineformset_factory(State, City, extra=2,  fields=("city_name",))


class BaseStateFormset(BaseInlineFormSet):
    def add_fields(self, form, index):
        super(BaseStateFormset, self).add_fields(form, index)

        # save the formset in the 'nested' property
        form.nested = CityFormset(
            instance=form.instance,
            data=form.data if form.is_bound else None,
            files=form.files if form.is_bound else None,
            prefix='address-%s-%s' % (
                form.prefix,
                CityFormset.get_default_prefix()),
            # extra=1
        )

    def is_valid(self):
        result = super(BaseStateFormset, self).is_valid()

        if self.is_bound:
            for form in self.forms:
                if hasattr(form, 'nested'):
                    result = result and form.nested.is_valid()

        return result

    def save(self, commit=True):

        result = super(BaseStateFormset, self).save(commit=commit)

        for form in self.forms:
            if hasattr(form, 'nested'):
                if not self._should_delete_form(form):
                    form.nested.save(commit=commit)

        return result


StateFormset = inlineformset_factory(Country, State, formset=BaseStateFormset, extra=2, fields=("state_name",))

views.py

from .models import Country, State, City

def manage_state(request, parent_id):

parent = get_object_or_404(Country, id=parent_id)

if request.method == 'POST':
    formset = forms.StateFormset(request.POST, instance=parent)
    if formset.is_valid():
        formset.save()
        # return redirect('parent_view', parent_id=parent.id)
        return redirect(reverse('india:manage_state', kwargs={"parent_id": parent.id}))

else:
    formset = forms.StateFormset(instance=parent)

return render(request, 'home.html', {
              'parent':parent,
              'children_formset':formset})

我想要的是一个单一的形式,它将根据国家的对象为父(国家)模型创建一个对象,为子(州)创建多个对象,并根据相应的州为孙子(城市)创建多个对象

例如:

<form method="POST">
    Parentform:(Country)
        <input name="country_name">


        Childform:(State)
            <input name="state_name">

            GrandChildform:(City)
                <input name = "City_name">

            <button> Add GrandChild</button>

        <button> Add Child </button>

    <button>Add Parent</button>

</form>

此外,添加按钮应该能够向表单动态添加更多国家、州和城市。

如有任何帮助、建议或参考,我们将不胜感激。 提前致谢。

我得到了解决方案。感谢 PYTHON 和 Django。

据我所知,我们可以使用内置包 django-nested-admin.

编辑我们自己的管理员

我们不需要构建自定义表单、视图或任何东西。

我正在分享我的 Django-admin 的图片: Image

为此,我正在分享说明:

首先我们使用pip安装一个包:

pip install django-nested-admin.

现在我们在settings.py中添加库:

INSTALLED_APPS[
    ...

    'nested_admin',

    ...
]

urls.py中添加库的url:

url(r'^nested_admin/', include('nested_admin.urls')),

admin.py中注册模型:

from django.contrib import admin
from .models import State, Country, City
from nested_admin import NestedModelAdmin, NestedStackedInline, NestedTabularInline


class CityTabularInline(NestedTabularInline):
    model = City
    extra = 1


class StateTabularInline(NestedTabularInline):
    model = State
    extra = 1
    inlines = [CityTabularInline, ]


class CountryAdmin(NestedModelAdmin):
    inlines = [StateTabularInline, ]

admin.site.register(Country, CountryAdmin)

用法:

NestedModelAdmin: to extend the django ModelAdmin class and to be able to use differents
types of classes in the inlines attribute.

NestedStackedInline: to allow the addition of TabularInline classes in the inlines
attribute.

NestedTabularInline: to extend the TabularInline.

更多详情请Visit