limit_choices_to Modelo = { 'user': user}

votos
11

Eu fui a toda a documentação, também eu fui para o canal IRC (BTW uma grande comunidade) e eles me disseram que não é possível criar um modelo e limitar as escolhas em um campo onde o 'usuário atual' está em um ForeignKey. Vou tentar explicar isto com um exemplo:

class Project(models.Model):
  name = models.CharField(max_length=100)
  employees = models.ManyToManyField(Profile, limit_choices_to={'active': '1'})

class TimeWorked(models.Model):
  project = models.ForeignKey(Project, limit_choices_to={'user': user})
  hours = models.PositiveIntegerField()

É claro que o código não funciona porque não há nenhum objeto 'usuário', mas essa foi a minha idéia e eu estava tentando enviar o objeto 'user' para o modelo apenas para limitar as escolhas que o usuário atual tem projetos, eu não 't quer ver projectos onde eu não estou.

Muito obrigado se você pode me ajudar ou me dar algum conselho, eu não quero que você escreva todo o aplicativo, apenas uma dica de como lidar com isso. Eu tenho 2 dias com este na minha cabeça e eu não posso descobrir isso :(

ATUALIZAÇÃO : A solução está aqui: http://collingrady.wordpress.com/2008/07/24/useful-form-tricks-in-django/ enviar request.usera um modelo.

Publicado 01/10/2008 em 23:14
fonte usuário
Em outras línguas...                            


7 respostas

votos
4

Próprio modelo não sabe nada sobre o usuário atual, mas você pode dar a este usuário em vista a forma que opera modelos objetos (e na redefinição de forma choicespara o campo necessário).

Se você precisar isso no site admin - você pode tentar raw_id_admin, juntamente com django-granular-permissions( http://code.google.com/p/django-granular-permissions/ mas eu não poderia rapidamente começar a trabalhar no meu django mas parece ser fresco suficiente para 1,0 por isso ...).

Por fim, se você precisa fortemente a selectbox em admin - então você precisa cortar django.contrib.admin-se.

Respondeu 02/10/2008 em 01:47
fonte usuário

votos
1

Usando views genéricas baseadas em classe em Django 1.8.x / Python 2.7.x, aqui é o que os meus colegas e eu vim com:

Em models.py:

# ...

class Proposal(models.Model):
    # ...

    # Soft foreign key reference to customer
    customer_id = models.PositiveIntegerField()

    # ...

Em forms.py:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.forms import ModelForm, ChoiceField, Select
from django import forms
from django.forms.utils import ErrorList
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
from .models import Proposal
from account.models import User
from customers.models import customer



def get_customers_by_user(curUser=None):
    customerSet = None

    # Users with userType '1' or '2' are superusers; they should be able to see
    # all the customers regardless. Users with userType '3' or '4' are limited
    # users; they should only be able to see the customers associated with them
    # in the customized user admin.
    # 
    # (I know, that's probably a terrible system, but it's one that I
    # inherited, and am keeping for now.)
    if curUser and (curUser.userType in ['1', '2']):
        customerSet = customer.objects.all().order_by('company_name')
    elif curUser:
        customerSet = curUser.customers.all().order_by('company_name')
    else:
        customerSet = customer.objects.all().order_by('company_name')

    return customerSet


def get_customer_choices(customerSet):
    retVal = []

    for customer in customerSet:
        retVal.append((customer.customer_number, '%d: %s' % (customer.customer_number, customer.company_name)))

    return tuple(retVal)


class CustomerFilterTestForm(ModelForm):

    class Meta:
        model = Proposal
        fields = ['customer_id']

    def __init__(self, user=None, *args, **kwargs):
        super(CustomerFilterTestForm, self).__init__(*args, **kwargs)
        self.fields['customer_id'].widget = Select(choices=get_customer_choices(get_customers_by_user(user)))

# ...

Em views.py:

# ...

class CustomerFilterTestView(generic.UpdateView):
    model = Proposal
    form_class = CustomerFilterTestForm
    template_name = 'proposals/customer_filter_test.html'
    context_object_name = 'my_context'
    success_url = "/proposals/"

    def get_form_kwargs(self):
        kwargs = super(CustomerFilterTestView, self).get_form_kwargs()
        kwargs.update({
            'user': self.request.user,
        })
        return kwargs

Em templates / propostas / customer_filter_test.html:

{% extends "base/base.html" %}

{% block title_block %}
<title>Customer Filter Test</title>
{% endblock title_block %}

{% block header_add %}
<style>
    label {
        min-width: 300px;
    }
</style>
{% endblock header_add %}

{% block content_body %}
<form action="" method="POST">
    {% csrf_token %}
    <table>
        {{ form.as_table }}
    </table>
    <input type="submit" value="Save" class="btn btn-default" />
</form>
{% endblock content_body %}
Respondeu 28/03/2019 em 01:50
fonte usuário

votos
1

Este limitador de opções para o usuário atual é um tipo de validação que precisa acontecer de forma dinâmica no ciclo do pedido, não na definição do modelo estático.

Em outras palavras: no ponto onde você está criando um exemplo deste modelo, você estará em um modo de exibição e, nesse ponto, você terá acesso para o usuário atual e pode limitar as escolhas.

Então você só precisa de um ModelForm costume de passar na request.user para, veja o exemplo aqui: http://collingrady.wordpress.com/2008/07/24/useful-form-tricks-in-django/

from datetime import datetime, timedelta
from django import forms
from mysite.models import Project, TimeWorked

class TimeWorkedForm(forms.ModelForm):
    def __init__(self, user, *args, **kwargs):
        super(ProjectForm, self).__init__(*args, **kwargs)
        self.fields['project'].queryset = Project.objects.filter(user=user)

    class Meta:
        model = TimeWorked

em seguida, na sua opinião:

def time_worked(request):
    form = TimeWorkedForm(request.user, request.POST or None)
    if form.is_valid():
        obj = form.save()
        # redirect somewhere
    return render_to_response('time_worked.html', {'form': form})
Respondeu 11/01/2011 em 10:52
fonte usuário

votos
1

Aqui é o Threadlocals e user Cookbook

Respondeu 02/10/2008 em 18:24
fonte usuário

votos
1

Use threadlocals se você deseja obter atual usuário que edita este modelo. Threadlocals middleware coloca usuário atual na variável de todo o processo. Tome este middleware

from threading import local

_thread_locals = local()
def get_current_user():
    return getattr(getattr(_thread_locals, 'user', None),'id',None)

class ThreadLocals(object):
    """Middleware that gets various objects from the
    request object and saves them in thread local storage."""
    def process_request(self, request):
        _thread_locals.user = getattr(request, 'user', None)

Verifique a documentação sobre como usar classes de middleware. Em seguida, em qualquer lugar no código que você pode chamar

user = threadlocals.get_current_user
Respondeu 02/10/2008 em 11:09
fonte usuário

votos
0

Eu não tenho certeza que eu entender completamente exatamente o que você quer fazer, mas eu acho que há uma boa chance de que você vai ter pelo menos parte do caminho até lá usando um Gerente de costume . Em particular, não tente definir seus modelos com restrições para o usuário atual, mas criar um gerenciador de que só retorna objetos que correspondem ao usuário atual.

Respondeu 02/10/2008 em 01:58
fonte usuário

votos
-1

Hmmm, eu não entendo perfeitamente a sua pergunta. Mas se você não pode fazê-lo quando você declara o modelo talvez você pode conseguir a mesma coisa com métodos de substituição da classe de objetos onde "enviar" o objeto de usuário, talvez começar com o construtor.

Respondeu 01/10/2008 em 23:24
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more