Django - Передача создателя формы в форму

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

Как передать создателя формы в форму?

Вот соответствующие модели:

class User(AbstractUser):
    pass

class AuctionListing(models.Model):
    title = models.CharField(max_length=64)
    description = models.CharField(max_length=512, default="")
    starting_bid = models.DecimalField(max_digits=6, decimal_places=2, default=0.01, validators=[MinValueValidator(Decimal('0.01'))])
    url = models.URLField(max_length=200, blank=True)
    category = models.CharField(max_length = 20)
    user = models.ForeignKey(User, on_delete=models.CASCADE, db_constraint=False, related_name="items")
    def __str__(self):
        return self.title

Вот мой файл forms.py:

class CreateListing(forms.ModelForm):
    category = forms.ModelChoiceField(queryset=Category.objects.all(), empty_label="No category")
    class Meta:
        model = AuctionListing
        fields = ('title', 'description', 'starting_bid', 'url', 'category', 'user')
        widgets = {
            'title': forms.TextInput(attrs={'placeholder':'Write your listing title here...'}),
            'description': forms.Textarea(attrs={'placeholder':'Write your comment here...', 'rows':3}),
        }

А вот моя попытка для вида:

def create_listing(request):
    form = CreateListing(request.POST)
    if request.method == "POST":
        if form.is_valid():
            form_data = form.save()
            form_data.user = request.user
            form_data.save()
            return HttpResponseRedirect(reverse("index"))
        else:
            print("RIP")
    return render(request, "auctions/create_listing.html", {
        "form" : CreateListing
    })

auctions/create_listing.html выглядит следующим образом:

<h1> Create new listing </h1>
<form action="" method="POST">
    {% csrf_token %}
        <label>Name*</label>
        <br>
        {{ form.title }}
    <br>
        <label >Description*</label>
        <br>
        {{ form.description }}
        <br>   
        <label >Starting bid*</label>
        <br>
        {{ form.starting_bid }}
        <br>  
        <label > Image url (optional) </label>
        <br>
        {{ form.url }}
        <br>  
        <label > Category (optional) </label>
        <br>
        {{ form.category }}
        <br> 
        <input type="hidden" name="user" value="{{request.user}}">
        <button type="submit" class="btn btn-primary save">Create your listing</button>
    
</form>

Ошибка, которую я получаю при этом: "BaseModelForm.init() получил неожиданный аргумент ключевого слова 'user'"

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

Замените {{ form.user }} на <input type="hidden" name="user" value="{{request.user}}">

Пользователь должен приходить автоматически, поэтому вам не нужно отображать поле пользователя во фронт-энде

вышеуказанным методом вы получите зарегистрированного пользователя, но все еще трудно сохранить, так как это внешний ключ, и то, что вы получите из front-end, будет иметь строковый тип.

Лучшим предложением будет следующий код.

    if form.is_valid():
        form_data = form.save()
        form_data.user = request.user
        form_data.save()

Добавьте аргумент user в метод __init__ формы. Вы можете установить пользователя прямо там, и нет необходимости даже отображать поле пользователя. Вы можете полностью скрыть его.

class CreateListing(forms.ModelForm):
    category = forms.ModelChoiceField(queryset=Category.objects.all(), empty_label="No category")
    class Meta:
        model = AuctionListing
        fields = ('title', 'description', 'starting_bid', 'url', 'category', 'user')
        widgets = {
            'title': forms.TextInput(attrs={'placeholder':'Write your listing title here...'}),
            'description': forms.Textarea(attrs={'placeholder':'Write your comment here...', 'rows':3}),
            'user': forms.HiddenInput(),
        }

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super().__init__(*args, **kwargs)
       
        self.fields['user'].initial = user.id

Не забудьте использовать пользовательский kwarg в представлении:

def create_listing(request):
    form = CreateListing(request.POST, user=request.user)
    if request.method == "POST":
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse("index"))
        else:
            print("RIP")
            # If form is invalid you should render the same template again
            # with the errors
            return render(request, "auctions/create_listing.html", {"form": form})
    return render(request, "auctions/create_listing.html", {
        # For the empty form, this needs to be an instance of the form,
        # and not a class
        "form" : CreateListing(user=request.user)
    })

Также вы можете заменить ваш HTML на:

{{ form.user }}
Вернуться на верх