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

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

Если пользователь А создаст категорию "Еда123", то пользователь Б не сможет ее увидеть. Он может создать свою собственную подобную категорию.

Я создал две модели - Category и Expense.

class Category(models.Model):
    name = models.CharField(max_length=100)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="category")

class Expense(models.Model):
    name = models.CharField(max_length=100)
    amount = models.DecimalField(max_digits=8, decimal_places=2)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="expense")

Я использую общее представление при создании расходов и категорий.

class ExpenseListView(LoginRequiredMixin, ListView):
model = Expense
context_object_name = 'expense'
template_name = 'expense/expense_list.html'

def get_queryset(self):
    return self.request.user.expense.all()

class ExpenseCreateView(CreateView):
    model = Expense
    success_url = '/record/expense'
    form_class = ExpenseForm

def form_valid(self, form):
    self.object = form.save(commit=False)
    self.object.user = self.request.user
    self.object.save()
    return HttpResponseRedirect(self.get_success_url())

class CategoryCreateView(CreateView):
    model = Category
    success_url = '/record/expense'
    form_class = CategoryForm

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.user = self.request.user
        self.object.save()
        return HttpResponseRedirect(self.get_success_url())

Более того, я использовал forms.py.

class ExpenseForm(forms.ModelForm):
    class Meta:
        model = Expense
        fields = ('name', 'amount', 'category')

class CategoryForm(forms.ModelForm):
    class Meta:
        model = Category
        fields = ('name',)

К сожалению, когда пользователь A создает категорию "IT", она автоматически переходит к пользователю B. Когда пользователь B создает свои расходы, он также видит эту категорию "IT", которую создал A, а не B.

Как ограничить отображение категорий в форме только теми, которые созданы определенным пользователем?

Проблема заключается в том, что вы не фильтруете поля модели по пользователю в ExpenseForm (как вы это делаете в ExpenseListView.get_queryset).

Чтобы сделать это, вам нужно немного изменить вашу логику. вы попробуете что-то вроде этого:

# forms.py
class ExpenseForm(forms.ModelForm):
    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # limit the category field queryset
        self.fields['category'] = forms.ModelChoiceField(
            queryset=user.category.all())
        )
    class Meta:
        model = Expense
        fields = ('name', 'amount', 'category')

# views.py
class ExpenseCreateView(CreateView):
    ...
    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        # inject the user in the form instantiation
        kwargs['user'] = self.request.user
        return kwargs

Надеюсь, это поможет вам!

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