django-models - 将当前登录的用户分配给 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
模型 [Django-doc]更好。有关更多信息,您可以查看文档的引用User
模型部分。
注意:在 Django 中,基于类的视图 (CBV) 通常有一个
…View
后缀,以避免与模型名称发生冲突。因此,您可能会考虑将视图类重命名为CreateProductView
,而不是。CreateProduct
推荐阅读
- etl - 如何提取所有行,满足特定条件的行?描述中的细节
- java - 如何从 http 请求目录中拆分密钥?
- ffi - 从 Chibi Scheme FFI 绑定中的 out 参数获取 struct*
- javascript - 如何解决 Uncaught (in promise) DOMException 错误?
- php - 无效的正文缩进级别(期望缩进级别至少为 4)
- node.js - 节点续集 (MSSQL) - 用户 '' 登录失败
- javascript - 交换大树的首选方式(例如 SPA 中的页面):`display: none`、`replaceChild()` 等
- node.js - 如何确定我的哪些依赖项取决于我的 node_modules 中的特定包?
- jquery - 如何压缩此 jquery 以允许无限数量的选项
- python - Python 和 Ruby 之间的匹配签名