forms.py 使用 ForeignKey 模型创建表单。商店应该只能将产品添加到自己的商店。 (姜戈)

Posted

技术标签:

【中文标题】forms.py 使用 ForeignKey 模型创建表单。商店应该只能将产品添加到自己的商店。 (姜戈)【英文标题】:forms.py creating forms with ForeignKey model. A store should only be able to add products to its own store. (Django) 【发布时间】:2021-11-16 13:57:55 【问题描述】:

商店应该只能为自己创造产品,不能为其他商店。

models.py

from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.text import slugify
from django.dispatch import receiver

class Store(models.Model):
    name = models.CharField(max_length=100)
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    slug = models.SlugField(unique=True, blank=False, null=False)


class Product(models.Model):
    store = models.ForeignKey(Store, on_delete=models.CASCADE, null=False, blank=False)
    name = models.CharField(max_length=200)
    price = models.FloatField()
    image = models.ImageField(null=True, blank=True)

forms.py

from .models import Store, Product
from django import forms

class AddProductForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)

        # restrict the queryset of 'Store'
        self.fields['store'].queryset = self.fields['store'].queryset.filter(
            owner=user)

    class Meta:
        model = Product
        fields = ('store', 'name', 'price', 'image',)

        widgets = 
            'name': forms.TextInput(attrs='class': 'form-control', 'placeholder': 'Name of your product'),
            'price': forms.NumberInput(attrs='class': 'form-control', 'placeholder': 'Price of your product'),
            'image': forms.FileInput(attrs='class': 'form-control'),
        

在我的 views.py 文件中,我尝试了不同的东西,但没有任何效果,所以我将其保留在那里,以便您知道我尝试了什么。

views.py

from django.shortcuts import render, redirect
from django.urls.base import reverse
from django.contrib.auth.models import User, Group
from django.contrib.auth import authenticate, login
from .models import Product, Store
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView


class AddProductView(CreateView):

    model = Product
    form_class = AddProductForm
    template_name = 'app1/add-product.html'



    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs


    def form_valid(self, form):
        form.instance.owner = self.request.user
        if Store.objects.filter(owner=self.request.user).exists():
            self.store = Store.objects.filter(Store__owner=self.request.user)

            form = form.cleaned_data
            form['store'] = self.store
            
            return super().form_valid(form)
            
        else:
            return super().form_invalid(form)

    

    
    def form_invalid(self, form):
        return super().form_invalid(form)

    
    def get_context_data(self, **kwargs):
        pass

    
    def get_success_url(self):
        return reverse('store', kwargs='slug': self.object.store.slug)

我不知道用谷歌搜索什么,我尝试过这些主题:

How to autofill variable with foreign key in django form?

Django - Forms - autofill & hide foreign key field

【问题讨论】:

***.com/questions/3010489/… @token 我正在使用基于类的视图,我应该替换什么而不是 user=user @token 成功了: ***.com/questions/51180119/… 现在它只需要一些调整,因为你为什么会有一个下拉菜单,当你只能选择一个东西时。 【参考方案1】:

只是 views.py

中的导入示例
from django.shortcuts import render, redirect
from django.urls.base import reverse
from django.contrib.auth.models import User, Group
from django.contrib.auth import authenticate, login
from .models import Product, Store
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView

views.py 中添加这个

class AddProductView(CreateView):

    model = Product
    form_class = AddProductForm
    template_name = 'app1/add-product.html'



  # add this code |
  #               V

    def get_initial(self):
        if Store.objects.filter(owner=self.request.user).exists():
            user = self.request.user
            initial = super(AddProductView, self).get_initial()
            initial['store'] = Store.objects.get(owner=user)
            return initial    


    ...

确保根据您的型号名称和需求对其进行编辑。


如果你想隐藏它,看看这个帖子Change a Django form field to a hidden field

【讨论】:

以上是关于forms.py 使用 ForeignKey 模型创建表单。商店应该只能将产品添加到自己的商店。 (姜戈)的主要内容,如果未能解决你的问题,请参考以下文章

如何以 django 模型形式覆盖保存方法

迁移与 forms.py 冲突

Django在forms.py中使用视图或url中的变量

在管理站点中更改 ForeignKey 的默认值

Flask构建微电影

Django将登录的登录用户保存为外键