django form set текущий логин пользователя - PullRequest
4 голосов
/ 10 ноября 2010
@login_required
def post_review(request):
    if request.method == 'POST':
        formset = ReviewForm(request.POST)
        if formset.is_valid():
            formset.save(commit=False)
            #formset.author = User.objects.get(pk=int(request.user.id))
            formset.pub_date = datetime.datetime.now
            formset.save()
            return HttpResponseRedirect(reverse(review_index))
    else:
        formset = ReviewForm()
    return render_to_response("review/post_review.html",
        {"formset": formset}, context_instance=RequestContext(request),
    )

У меня есть это представление, я хочу автоматически установить текущего вошедшего в систему пользователя в поле автора моей формы обзора. Но я не знаю как. Любые идеи / подсказка пожалуйста? Ниже моя форма:

class ReviewForm(ModelForm):
    class Meta:
        model = Review
        fields = ('title','category', 'body', )
        widgets = {
            'body': Textarea(attrs={'cols': 60, 'rows': 20}),
        }

Ответы [ 3 ]

15 голосов
/ 10 ноября 2010

Я всегда делал это, принимая новый kwarg в форме __init__ и сохраняя значение до времени сохранения.

class ReviewForm(ModelForm):
    class Meta:
        model = Review
        fields = ('title','category', 'body', )
        widgets = {
            'body': Textarea(attrs={'cols': 60, 'rows': 20}),
        }

    def __init__(self, *args, **kwargs):
        self._user = kwargs.pop('user')
        super(ReviewForm, self).__init__(*args, **kwargs)

    def save(self, commit=True):
        inst = super(ReviewForm, self).save(commit=False)
        inst.author = self._user
        if commit:
            inst.save()
            self.save_m2m()
        return inst

И затем, на мой взгляд:

def post_review(request):
    # ... snip ...
    if request.method == 'POST'
      form = ReviewForm(request.POST, user=request.user)
      if form.is_valid():
         form.save()
         return HttpResponseRedirect('/thanks/') #or whatever the url
      else:
         # Don't forget to add user argument
         form = ReviewForm(user=request.user)
    # ... snip ...

Если Review.author не является обязательным полем, вы можете добавить второе значение к вызову kwargs.pop, чтобы установить значение по умолчанию, например None.В противном случае, если user kwarg не предоставлен, он выдаст ошибку, фактически сделав ее обязательным аргументом.

2 голосов
/ 10 ноября 2010

У меня есть mixin mixin, который позволяет передавать дополнительные аргументы сгенерированным формам. Просто добавьте mixin в качестве первого базового класса, установите словарь с именем "form_kwargs" в качестве атрибута класса для описания аргументы для передачи.


from django.forms.formsets import BaseFormSet</p>

<p>class BaseKwargsFormSet(BaseFormSet):
    """
    A formset mix-in to allow keyword arguments to be passed to constructed forms</p>

For model_formsets, derive from this model *first* because django's formsets
can't grok the extra arguments.

To use, specify a dictionary with the kwargs & default values as an attribute
named "form_kwargs" on the formset base class.

example:

class BaseUserModelFormset (BaseKwargsFormSet, BaseModelFormSet):
    form_kwargs = { 'user': None }

UserFormset = modelformset_factory (usermodel, form=userform,
                                    formset=BaseUserModelFormset)

formset = UserFormset (request.POST or None, user=request.user)
"""
def __init__(self, *args, **kwargs):
    form_kwargs = getattr(self, 'form_kwargs', {})
    self.form_kwargs = dict((k, kwargs.pop(k, v)) for k, v in form_kwargs.items())
    super(BaseKwargsFormSet, self).__init__(*args, **kwargs)

def _construct_form(self, index, **kwargs):
    kwargs.update(**self.form_kwargs)
    return super(BaseKwargsFormSet, self)._construct_form(index, **kwargs)
0 голосов
/ 24 мая 2019

В качестве альтернативного решения, в Django 2+ с использованием представления формы - такого как CreateView или FormView, я могу просто передать self.request.user в мою предварительно сохраненную модель формы:

class AppCreateView(CreateView):
    model = models.App
    fields = ['name']
    success_url = '/thanks/'

    def form_valid(self, form):
        app_model = form.save(commit=False)
        app_model.author = self.request.user
        # app_model.user = User.objects.get(user=self.request.user) # Or explicit model 
        app.save()
        return super().form_valid(form)

Я согласен, что представление на основе классов здесь не важно. Важная строка - app_model.author = self.request.user.

Модель не особенная:

from django.db import models
from django.contrib.auth.models import User


class App(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=255, help_text="Arbitrary name")
    created = models.DateTimeField(auto_now_add=True, max_length=255)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...