Django Форма: показывать только многие объекты от зарегистрированного пользователя - PullRequest
1 голос
/ 17 февраля 2020

В настоящее время проблема заключается в том, что моя форма показывает зарегистрированному пользователю все портфолио ios, когда-либо созданные. В форме должен отображаться только портфель ios, созданный вошедшим в систему пользователем.

Примерно так:

associated_portfolios manytomany field = ...objects.filter(user=user_id)

Я не уверен, должно ли это быть реализовано в forms.py или views.py, и если да, то как. Я просматривал документацию django и нашел 'formfield_for_manytomany', но не уверен, что это только для администратора.

Models.py

class Portfolio(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=20)
    description = models.CharField(max_length=250, blank=True, null=True)

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=50)
    body = RichTextUploadingField(blank=True, null=True)
    associated_portfolios = models.ManyToManyField(Portfolio, blank=True)
    created_on = models.DateField(auto_now_add=True, editable=False)

Views.py

class PostCreate(CreateView):
    model = Post
    form_class = PostCreateForm

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        self.fields['associated_portfolios'] = Portfolio.objects.filter(user=self.request.user)
        return super().formfield_for_manytomany(db_field, request, using=self.using, **kwargs)

forms.py

class PortfolioCreateForm(ModelForm):
    class Meta:
        model = Portfolio
        fields = ['user', 'name', 'description']    

class PostCreateForm(ModelForm):
    class Meta:
        model = Post
        fields = ['user', 'title', 'body', 'category', 'associated_portfolios']

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Поскольку вы используете ModelForm, поле associated_protfolios будет иметь вид ModelMultipleChoiceField [ docs ]. Это поле имеет атрибут queryset [ docs ]. Мы хотим изменить этот атрибут.

Django CreateView имеет метод get_form, который в этом случае захватит ваш PostCreateForm. Это хорошее место для фильтрации набора запросов поля, так как у нас есть доступ к пользователю:

class PostCreate(CreateView):
    model = Post
    form_class = PostCreateForm

    def get_form(self, *args, **kwargs):
        form = super().get_form(*args, **kwargs)  # Get the form as usual
        user = self.request.user
        form.fileds['associated_portfolios'].queryset = Portfolio.objects.filter(user=user)
        return form
0 голосов
/ 19 февраля 2020

Вы пробовали это

self.fields['associated_portfolios'] = Post.objects.filter(associated_portfolios__portfolio__user=request.user)

ИЛИ

user_posts = Post.objects.filter(user=request.user)
self.fields['associated_portfolios'] = user_posts.associated_portfolios.all()

Узнайте больше об отношениях M2M, запрашивающих здесь , потому что я думаю, что ваша проблема может быть с этим.

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

И, наконец, добавьте related_name к полям модели, чтобы вы могли легко использовать его для обратных отношений, вместо того, чтобы использовать именование по умолчанию Django, оно будет более понятным и даст лучшее понимание.

...