user15440172
user15440172

Reputation: 134

Link the current user to a field in ModelForm django

I'm working on a commerce site using django. The logged in user has the ability to create a listing. I'm using django model to create a model and ModelForm for forms.

models.py

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


class User(AbstractUser):
    pass

class Listing(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField(max_length=500)
    starting_bid = models.IntegerField()
    image_url = models.URLField(blank=True)
    category = models.CharField(max_length=15, blank=True)
    listed_by = models.ForeignKey(User, on_delete=models.CASCADE)

The last field in Listing(models.Model) is used to store the user who listed the listing which should be based on the current logged in user.

forms.py

from django import forms

from .models import Listing


class ListingForm(forms.ModelForm):
    class Meta:
        model = Listing
        fields = ["title", "description", "starting_bid", "image_url", "category"]

forms.py without the listed_by field is working as intended.

views.py

def create(request):
    """Renders a Form to Create a Listing"""

    if request.method == "POST":

        # Create a form instance and populate it with data from the request:
        form = ListingForm(request.POST)

        if form.is_valid():
            # Save a new Listing object from the form's data.
            listing = form.save()

            # Redirects the users to the main page
            return HttpResponseRedirect(reverse("index"))

        # If the form is not valid, render the template with errors
        return render(request, 'auctions/create_listing.html', {"form": form})

    # Create a form instance and pass it to the template
    form = ListingForm()
    return render(request, "auctions/create_listing.html", {"form": form})

Here, I classified how I handle this form.

Problem

My problem arises when I want to link the current logged in user to Listing model, so I've searched for answers which unfortunately didn't clear my concerns due to the fact that I'm using a ModelForm.

What have I tried? I've read the documentation on this and the stackoverflow's answers among them:

Is the proposed links the best approach to my problem? If so, how should I use it? Should I use it in models.py, forms.py or views.py?

Is there a better approach?

Upvotes: 1

Views: 966

Answers (2)

Nabil El Houssein
Nabil El Houssein

Reputation: 98

The best approach you can take to solve your problem is by adding listed_by in views.py.

According the Django's Documentation.

If you call save() with commit=False, then it will return an object that hasn’t yet been saved to the database... This is useful if you want to do custom processing on the object before saving it...

so in views.py add the following:

if form.is_valid():
    # Save a new Listing object from the form's data.
    listing = form.save()

    listing.listed_by = request.user
    listing.save()

    # Redirects the users to the main page
    return HttpResponseRedirect(reverse("index"))

Upvotes: 1

Anthony
Anthony

Reputation: 959

You can get a model object without saving it and add to it using commit=False

if form.is_valid():
    # Save a new Listing object from the form's data.
    listing = form.save(commit=False)
    listing.listed_by = request.user
    listing.save()

Upvotes: 2

Related Questions