2013-11-10 2 views
1

Вот три очень упрощенный класса я работаю с:Dynamic SQL присоединиться запросом в Джанго

class User(AbstractBaseUser): 
    email = models.EmailField() 
    name = models.CharField() 
    is_admin = models.BooleanField() 
    phone_number = models.CharField()  

class Accounts(models.Model): 
    name = models.CharField() 
    users = models.ManyToManyField(settings.USR_MODEL, through='Membership', 
     null=True, blank=True) 
    customer_id = models.IntegerField()  

class Membership(models.Model): 
    user = models.ForeignKey(User) 
    company = models.ForeignKey(Accounts) 
    is_admin = models.BooleanField(default=False) 
    is_billing = models.BooleanField(default=False) 
    is_tech = models.BooleanField(default=False) 

Я хотел бы быть в состоянии получить пользователь, связанные с аккаунтом и фильтровать их по булевым атрибутам is_admin, is_billing, is_tech. Сейчас я делаю:

microsoft = Accounts.objects.get(customer_id=1) 

Затем я могу получить техническую связь, делая

ms_tech = microsoft.filter(membership__is_tech=True) 

Это работает, однако, я хотел бы иметь возможность динамически создавать запросы для membership__is_tech/__is_billing/__is_admin/__is_foo/__is_bar/__is_quux/etc. Каков самый пифонический/djangonic способ сделать это?

+0

Какими будут критерии фильтра? Вы хотите И или ИЛИ в зависимости от некоторых критериев? – karthikr

+0

Мне просто нужно отфильтровать по одному типу атрибутов из Учетной записи. В приведенном выше примере я просто вернул ms_tech. В отдельном запросе я могу фильтровать is_foo или что угодно. – LiavK

ответ

1

Я не совсем уверен, что вы подразумеваете под динамическим созданием запросов, учитывая, что у вас есть только определенное количество полей. Но возможно, вы можете использовать тот факт, что запрос является ключевым словом аргумента функции, и как таковой может быть заменен со словарем и ** синтаксиса:

kwargs = {'membership__is_tech': True} 
ms_tech = microsoft.filter(**kwargs) 

(Обратите внимание, что не должна быть в фильтре нет objects вы даете, так как microsoft уже набор запросов, а не модель.)

+0

Правильно, я думаю, это должно сработать, спасибо! Кстати, я исправил опечатки объектов - я писал эту часть вопроса из памяти. – LiavK

1

Наиболее вещий/djangonic (а также наиболее нормализуется) способ сделать это было бы не включают is_billing/is_admin/is_tech к модели членства в поля, но добавить поле «отдел», который мог бы получить " admin/billing/tech "(или является ForeignKey для вашей модели отдела).

Если вы хотите иметь два отдела (например, admin и blling), то добавьте поле ManyToMany в модель отдела.

+0

Интересно. Я могу изучить эту возможность, но это часть большей базы кода, и я сомневаюсь, что смогу изменить эту деталь реализации. – LiavK

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