My problem is I cannot auto assign my logged in user in seller instance of my model. I have tried many solutions from stackoverflow but none of them worked. I dont know what the problem is. I have tried both class based view and function based view. Here is class based approach.
My model:
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
class Product(models.Model):
title = models.CharField(max_length= 100)
price = models.DecimalField(decimal_places=2, max_digits=9, default=0.00)
description = models.TextField()
discount_price = models.DecimalField(decimal_places=2, max_digits=8, default=0.00)
image = models.ImageField(upload_to='product_image/', default="default.jpg", blank=True,
null=True)
seller = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
image = Image.open(self.image.path)
if (image.height > 300 and image.width > 300):
output_size = (300, 300)
image.thumbnail(output_size)
image.save(self.image.path)
My view:
from django.shortcuts import render, redirect
from .models import Product
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import CreateView
from django.urls import reverse_lazy
class CreateProduct(LoginRequiredMixin, CreateView):
model = Product
fields = '__all__'
template_name = 'product/product_create.html'
success_url = reverse_lazy('home')
def form_valid(self, form):
form.instance.seller = self.request.user
return super().form_valid(form)
My Urls:
from django.urls import path
from .views import CreateProduct, detail_product, delete_product, update_product
app_name = 'product'
urlpatterns = [
path('create', CreateProduct.as_view(), name='create'),
]
My template:
{% extends 'base.html' %}
{% load crispy_forms_tags%}
{% block main %}
<div class="container mt-3">
<form action="{% url 'product:create' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form|crispy}}
<button type="submit" class="btn btn-warning">ADD</button>
</form>
</div>
{% endblock %}
You should not specify
fields = '__all__'
, since then the form will include a form element for theseller
in the form, and overwrite therequest.user
. This will thus "undo" the logic of theform.instance.seller = request.user
.You can exclude the field with:
An alternative, and perhaps more elegant, is to mark the field as non-editable: