【问题标题】:How do I filter values in a Django 1.7 form using ModelForm?如何使用 ModelForm 过滤 Django 1.7 表单中的值?
【发布时间】:2017-01-29 23:25:59
【问题描述】:

我正在尝试使用 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 子集?

【问题讨论】:

    标签: django django-models django-forms django-templates django-views


    【解决方案1】:

    AgregarProductoNewProduct 一样,对吗?我希望你用英语告诉我们...

    您需要来自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'
        ),
    ]
    

    希望对你有帮助..

    【讨论】:

    • 谢谢朋友,但我需要的是模板中只留下用户登录的部分,而不是所有用户的部分,如果你能帮助我,我将不胜感激。
    • 您可以使用包装器@login_required 或自定义包装器以要求用户必须登录..
    • 你可以在这一行看到:Secciones.objects.filter(user=request.user),它只过滤当前访问者/用户的Secciones。查看我的更新...
    【解决方案2】:

    您似乎想要提供一组过滤的部分,因此您可以在构建表单时使用初始参数:

    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 作为值和名称作为显示。

    【讨论】:

      猜你喜欢
      • 2011-03-01
      • 2012-04-29
      • 2010-09-22
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多