将当前LoggedIn用户分配给Django中的ForeignKey字段

问题描述

我的问题是我不能在模型的卖方实例中自动分配登录用户。我已经尝试了很多来自stackoverflow的解决方案,但是没有一个起作用。我不知道问题是什么。 我已经尝试了基于类的视图和基于函数的视图。这是基于类的方法。

我的模特:

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)

我的观点:

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) 

我的祝福:

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'),]

我的模板:

{% 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 %}

解决方法

您不应指定fields = '__all__',因为此后表单将在表单中包含seller的表单元素,并覆盖request.user。因此,这将“撤消” form.instance.seller = request.user的逻辑。

您可以使用以下方法排除该字段:

class CreateProduct(LoginRequiredMixin,CreateView):
    model = Product
    # no seller
    fields = ['title','price','description','discount_price','image']
    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)

另一种方法(也许更优雅)是将字段标记为不可编辑:

class Product(models.Model):
    # …
    seller = models.ForeignKey(User,editable=False,on_delete=models.CASCADE)

注意:与直接使用settings.AUTH_USER_MODEL [Django-doc]相比,通常最好使用User model [Django-doc]来引用用户模型。有关更多信息,请参见referencing the User model section of the documentation


注意:在Django中,基于类的视图(CBV)通常带有一个…View后缀,以避免与模型名称冲突。 因此,您可以考虑将视图类重命名为CreateProductView,而不是 CreateProduct

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...