1

Я пытаюсь использовать ModelForm для добавления моих данных. Он работает хорошо, за исключением того, что раскрывающийся список ForeignKey показывает все значения, и я хочу, чтобы он отображал значения, которые уместны для зарегистрированного пользователя.Как фильтровать значения в форме Django 1.7 с помощью ModelForm?

Это мои модели:

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, где secciones.user равно зарегистрированному пользователю?

ответ

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

Надеется, что это полезно ..

+0

Спасибо, но мне нужно, чтобы в шаблоне оставались только разделы входа пользователя, а не разделы всех пользователей, я был бы очень признателен, если вы можете мне помочь. –

+0

вы можете использовать wrapper ['@ login_required'] (https://docs.djangoproject.com/en/dev/topics/auth/default/#django.contrib.auth.decorators.login_required) или настраивать свою оболочку, чтобы потребовать пользователя должен войти в систему. –

+0

a вы можете видеть в этой строке: 'Secciones.objects.filter (user = request.user)', это только фильтрация 'Secciones' для текущего посетителя/пользователя. см. мое обновление ... –

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 

Это отображает только разделы пользователя в раскрывающемся списке, используя идентификатор как значение и имя как отображение.

Смежные вопросы