django form set current login user

前端 未结 3 1783
猫巷女王i
猫巷女王i 2020-12-10 08:55
@login_required
def post_review(request):
    if request.method == \'POST\':
        formset = ReviewForm(request.POST)
        if formset.is_valid():
            fo         


        
相关标签:
3条回答
  • 2020-12-10 09:20

    I have a formset mixin which lets you pass extra arguments to the generated forms. Just add the mixin as the first base class, set a dictionary named "form_kwargs" as a class attribute to describe the arguments to pass.

    
    from django.forms.formsets import BaseFormSet

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

    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 讨论(0)
  • 2020-12-10 09:29

    As an alternative solution, in Django 2+ using a form view - such as a CreateView or FormView, I can simply pass the self.request.user to my pre-saved form model:

    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)
    

    I agree the class based view is not important here. The important line is app_model.author = self.request.user.

    The model is not special:

    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)
    
    0 讨论(0)
  • 2020-12-10 09:41

    I've always done this by accepting a new kwarg in my form's __init__, and saving the value until save-time.

    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
    

    And then in my view:

    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 ...
    

    If Review.author isn't a required field, you can add a second value to the kwargs.pop call to set a default, like None. Otherwise, if the user kwarg isn't provided, it'll raise an error, effectively making it a required argument.

    0 讨论(0)
提交回复
热议问题