Django добавляет фильтр в раскрывающийся список ForeignKey

В моем приложении Django есть предметы и местоположения. Каждый элемент может быть связан с местоположением. В представлении элемента я хочу, чтобы пользователь мог выбирать только те места, которыми он владеет.

Учитывая следующие модели:

from django.conf import settings
from rules.contrib.models import RulesModel

# Create your models here.

class Location(RulesModel):
    name = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)


class Item(RulesModel):
    name = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    location = models.ForeignKey(
        Location, on_delete=models.SET_NULL, null=True, blank=True
    )
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

Как задать фильтр для ограничения мест, доступных в представлении?

from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin

# Create your views here.
from .models import Item

class ItemCreateView(LoginRequiredMixin, generic.CreateView):
    model = Item
    fields = [
        "name",
        "description",
        "location",
        "owner",
    ]
    success_url = reverse_lazy("item:item-list")

    def get_initial(self):
        return {"owner": self.request.user.id}

Я пробовал добавить def __init__() в представление и указать limit_choices_to в модели, оба безуспешно. Есть другие идеи?

Вы должны указать form_class в вашем представлении создания.

from .forms import ItemCreateForm

class ItemCreateView(LoginRequiredMixin, generic.CreateView):
    model = Item
    form_class = ItemCreateForm
    fields = [
        "name",
        "description",
        "location",
        "owner",
    ]
    success_url = reverse_lazy("item:item-list")

    def get_initial(self):
        return {"owner": self.request.user.id}

В forms.py отфильтруйте поле в __init__:

from django import forms

from .models import Location, Item

class ItemCreateForm(forms.ModelForm):
    class Meta:
        model = Item
        fields = [
            "name",
            "description",
            "location",
            "owner",
        ]

    def __init__(self, *args, **kwargs):
        super(ItemCreateForm, self).__init__(*args, **kwargs)
        self.fields['location'] = forms.ModelChoiceField(
            queryset=Location.objects.filter(), # <- Here goes your filters
        )

Для передачи request.user в случае, если вы пытаетесь фильтровать owner=user, смотрите здесь.

Вернуться на верх