我正在尝试使用ModelForm来添加我的数据。它运行良好,但ForeignKey下拉列表显示所有值,我只希望它显示与登录用户相关的值。
这些是我的模特:
class productos(models.Model):
user = models.ForeignKey(User)
secciones = models.ForeignKey(secciones)
name = models.CharField(max_length=50)
image = models.ImageField(upload_to = 'productos')
precio = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
descripcion = models.TextField(max_length=300, null=True,blank=True)
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.name)
super(productos, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
#####################################################################
class secciones(models.Model):
name = models.CharField(max_length=50)
user = models.ForeignKey(User)
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.name)
super(secciones, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
表单代码:
class AgregarProducto(forms.ModelForm):
class Meta:
model = productos
最后,查看代码:
def agregar_producto(request):
if request.method == "POST":
modelform = AgregarProducto(request.POST,request.FILES,user=request.user)
print modelform
if modelform.is_valid():
modelform.save()
return redirect("/editar-perfil/")
else:
modelform = AgregarProducto()
return render(request, "home/AgregarProducto.html", {"form":modelform})
如何让表单只显示secciones.user等于登录用户的secciones子集?
答案 0 :(得分:0)
AgregarProducto
是NewProduct
对吗?我希望你用英语告诉我们......
您需要secciones
中的特定对象,示例如下图所示;
<强> 1。 yourapp/models.py
强>
class Secciones(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=50)
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.name)
super(Secciones, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
class Productos(models.Model):
user = models.ForeignKey(User)
secciones = models.ForeignKey(Secciones)
name = models.CharField(max_length=50)
image = models.ImageField(upload_to = 'productos/%Y/%m/%d/')
precio = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
descripcion = models.TextField(max_length=300, null=True,blank=True)
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.name)
super(Productos, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
<强> 2。 yourapp/forms.py
强>
class AgregarProducto(forms.ModelForm):
class Meta:
model = Productos
fields = '__all__'
exclude = ['user', 'secciones']
第3。 yourapp/views.py
强>
from django.shortcuts import (render, redirect, get_object_or_404)
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from yourapp.models import (Secciones, Productos)
from yourapp.forms import AgregarProducto
@login_required
def agregar_producto(request):
"""
add new product view.
"""
template_name = 'home/AgregarProducto.html'
secciones = Secciones.objects.filter(user=request.user)
if secciones.exists() == False:
# do stuff, eg:
return redirect('/error/page')
if request.method == 'POST':
form = AgregarProducto(request.POST, request.FILES)
if form.is_valid():
initial_object = form.save(commit=False)
initial_object.user = request.user # here you save current user logged in.
# and also the `secciones` set single object,
# because I see in your model is `ForeignKey`
initial_object.secciones = secciones.first()
initial_object.save()
form.save()
# you also can redirect to the saved object
# an example;
return redirect(reverse('edit_product_page', kwargs={'pk': initial_object.pk}))
else:
context = {'form': form, 'errors': form.errors}
return render(request, template_name, context)
else:
form = AgregarProducto()
return render(request, template_name, {'form': form})
@login_required
def edit_product(request, pk):
"""
`productos` is from your model:productos
I suggest you to use `uppercase` in your class name;
eg: `Productors` but not `productos`
:param `pk` is pk/id from instance object of `productos`
"""
template_name = 'homee/edit_product.html'
product = get_object_or_404(Productos, pk=pk)
if request.method == 'POST':
# instance the form from object of `product` above.
form = AgregarProducto(request.POST, request.FILES, instance=product)
if form.is_valid():
initial_object = form.save(commit=False)
initial_object.user = product.user # set from user creation
initial_object.save()
form.save()
#do stuff
第3。 urls.py
强>
from django.conf.urls import url
from yourapp.views import (agregar_producto, edit_product)
urlpatterns = [
url(
r'^product/new/$',
agregar_producto, name='new_product_page'
),
url(
r'^product/(?P<pk>[-\d]+)/edit/$',
edit_product, name='edit_product_page'
),
]
希望它有用......
答案 1 :(得分:0)
看起来你想要的是提供一组过滤的部分,这样你就可以在构建表单时使用初始参数:
def agregar_producto(request):
if request.method == "POST":
modelform = AgregarProducto(request.POST,request.FILES,user=request.user)
print modelform
if modelform.is_valid():
modelform.save()
return redirect("/editar-perfil/")
else:
modelform = AgregarProducto(initial={'user':request.user}) #pass in the authenticated user
return render(request, "home/AgregarProducto.html", {"form":modelform})
然后以你的形式:
class AgregarProducto(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(AgregarProducto, self).__init__(*args, **kwargs)
if kwargs.get('initial'):
user = kwargs.get('initial').get('user')
if user:
sections = secciones.objects.filter(user_id=user.id)
self.fields['secciones'].choices = [(s.id, s.name) for s in sections]
self.fields['client'].choices = [('', '---------')]+self.fields['client'].choices #this adds an "empty" option
class Meta:
model = productos
这只会在下拉列表中显示用户的部分,使用id作为值和名称作为显示。