Проблема взаимоотношений Django M2M с администратором при использовании промежуточной таблицы с множественным выбором - PullRequest
0 голосов
/ 24 апреля 2019

Я работаю с отношениями m2m, используя для установки промежуточную таблицу.Проблема в том, что мне нужно показать множественный выбор вместо обычного перетаскивания, но когда я выбираю несколько элементов и сохраняю, я получаю сообщение об ошибке.

ValueError: Cannot assign "<QuerySet [<Facility: facility1>, <Facility: facility2>]>": "Property.facility" must be a "Facility" instance.

Также я показываю эту модель в admin.TabularInlineкоторый позволяет мне выбирать только один элемент в строке, так как в табличной форме он позволяет вставлять несколько форм.

Я пробовал несколько решений, таких как выборочное сохранение и многие другие, и кое-что, как я могу сохранить это, но появляется проблемана вид.Мне нужно показать только одну форму с множественным выбором виджета, чтобы выполнить этот выбор.

models.py


class Facility(models.Model):
    name = models.CharField(max_length=200)

class Property(models.Model):
    name = models.CharField(max_length=200)
    area = models.CharField(max_length=200)
    facility = models.ManyToManyField(Facility, through="PropertyFacility")

class PropertyFacility(models.Model):
    prop = models.ForeignKey(
        Property, related_name="facilities", on_delete=models.CASCADE
    )
    facility = models.ForeignKey(
        Facility, related_name="properties", on_delete=models.CASCADE
    )

admin.py


from django.contrib.admin.widgets import FilteredSelectMultiple
from django.utils.translation import ugettext_lazy as _

class PropertyFacilityForm(forms.ModelForm):
    facility = forms.ModelMultipleChoiceField(Facility.objects.all(), required=True, widget=FilteredSelectMultiple(_('ss'), False, attrs={'rows':'10'})

class PropertyFacilityInline(admin.TabularInline):
    model = Property.facility.through
    form = PropertyFacilityForm

class PropertyAdmin(TabbedModelAdmin):
    model = Property
    tab_facilities = (PropertyFacilityInline,)
    tab_property = (
        (
            "Property Details",
            {
                "fields": (
                    "name",
                    "area",
                )
            },
        ),
    )

    tabs = [
        ("Property", tab_property),
        ("Facilities", tab_facilities),
    ]

Это позволяет мне показать наАдминистратор, как это Здесь вы можете видеть, что я могу выбрать множественный выбор, но здесь должна быть одна форма, а не несколько.

Я хочу показать только одну единственную форму с виджетом для нескольких выборок, который позволяет мне выбирать и сохранять несколько элементов.а затем в change_view показывает выбранный и оставленные невыбранные.

1 Ответ

0 голосов
/ 28 апреля 2019

Я исправил проблему, добавив некоторую настраиваемую логику для сохранения поля m2m.

admin.py

class PropertyForm(forms.ModelForm):
    facility = forms.ModelMultipleChoiceField(Facility.objects.all(), required=False, widget=forms.CheckboxSelectMultiple)
    class Meta:
        model = Property
        fields = ["id", "name", "area", "city"]

    def save(self, commit=True):
        prop_facilities = self.cleaned_data.pop('facility')
        instance = forms.ModelForm.save(self, commit=False)
        instance.facility.clear()
        for facility in prop_facilities:
            PropertyFacility.objects.create(facility=facility, prop=instance)
        return instance


class PropertyAdmin(TabbedModelAdmin):
    model = Property
    tab_facilities = (("Facilities", {"fields": ("facility", )},),)
    tab_property = (
        (
            "Property Details",
            {
                "fields": (
                    "name",
                    "area",
                )
            },
        ),
    )

    tabs = [
        ("Property", tab_property),
        ("Facilities", tab_facilities),
    ]
...