pythondjango-modelsdjango-viewsdjango-formsdjango-timezone

Django timezone.now() returning None


I know I could use auto_now_add equals True but it bugs me that I can't get this simple view to work.

Here is the view:

def create(request):
    if request.method == "POST":
        form = CreateListing(request.POST)
        if form.is_valid:
            form.save(commit=False)
            form.date = timezone.now()
            form.save()
            return HttpResponseRedirect(reverse("index"))
    else:
        form = CreateListing()
        return render(request, "auctions/create.html", {
                "form": form
            })

Here is the form:

class CreateListing(forms.ModelForm):
    class Meta:
        model = Listing
        fields = ("name", "description", "bid")

Here is the model:

class Listing(models.Model):
    name = models.CharField(max_length=50)
    description = models.TextField()
    bid = models.DecimalField(max_digits=8, decimal_places=2)
    date = models.DateTimeField(null=True, blank=True)
    #date = models.DateTimeField(auto_now_add=True)

    def place(self):
        self.date = timezone.now()
        self.save()

    def __str__(self):
        return f"{self.name} going for {self.bid} since {self.date}"

I have tried removing the place function from the model, removing

form.save(commit=False)

and using datetime instead of timezone. I have wasted too many hours on this, please help!

The only way I can get something to work is creating an object through the shell and using the place function there. However, despite my timezone being set to America/Vancouver, it gives UTC time.


Solution

  • You need to update the instance returned when using commit=False, and not the form, so:

            if form.is_valid:
                instance = form.save(commit=False)
                instance.date = timezone.now()
                instance.save() 
    

    or since you wrote a place method in your model:

            if form.is_valid:
                instance = form.save(commit=False)
                instance.place()
    

    Although place() can probably be renamed to something better? But I would suggest just using auto_now_add.