0

我有以下模型结构,其中每个 Tradesman 具有具有两个属性的多对多关系;语言和纪律。在表单中,用户可以通过过滤这些属性来选择 Tradesman 的子集。

我想要发生的是:

  1. 如果用户只过滤一个属性,表单会选择所有未过滤的属性。例如。如果选择 a 选择语言但将学科留空,则不会过滤学科。
  2. 如果用户过滤一个商人没有一组的语言(即它为空),它会排除该商人。

我想我可以通过从查询中提取主键并使用它们的巴洛克式非 pythonesque 非 django 方法来解决这个问题,但宁愿使用更清洁的方法。

我认为可以解决的问题是:

  1. 一个动态的 django 过滤器,它会根据 if-else 逻辑删除或包含条件
  2. 一个与我可以存储在变量中的所有内容(包括空值)匹配的参数,例如。

     return_everything=**everything()!** 
     Q(discipline__id__in=return_everything)
    

我一直在查看 django 文档和 stackoverflow,但也找不到方法。谢谢你的帮助。

模型.py:

class Discipline(models.Model):  
    discipline=models.CharField(max_length=200, unique=True)

class Language(models.Model):  
    language=models.CharField(max_length=200, unique=True)

class Tradesman(models.Model):  
    discipline=models.ManyToManyField(Discipline, blank=True, null=True)
    language=models.ManyToManyField(Language, blank=True, null=True)

表格.py

class TradesmanForm(forms.Form):
    #select all values to output in the form
    discipline_all=.Discipline.objects.all() 
    language_all=Language.objects.all() 

    #declare form variables
    discipline=forms.ModelMultipleChoiceField(queryset=discipline_all,required=False)  
    language=forms.ModelMultipleChoiceField(queryset=language_all,required=False) 

    #clean data
    def clean(self) 
        cleaned_data=super(TradesmanForm, self).clean()
        return cleaned_data

视图.py

def TrademanLookup(request)
    if request.method == 'POST':      
        if form.is_valid()
            discipline=form.cleaned_data['discipline']
            language=form.cleaned_data['language']
            #################################################
            #  how can I make the below query dynamic,      # 
            #  or else pass a variable into it that selects # 
            #  everything, including nulls?                 #
            #################################################
            tradesman_return=Tradesman.objects.filter(
                Q(discipline__id__in=discipline),
                Q(language__id__in=language)
                )
            ...work with returned data...
        else:
            ...something else...
    else:
            ...something else...

    return render_to_response('some.html','somevar':somevar)
4

1 回答 1

1
def TrademanLookup(request)
    if request.method == 'POST':      
        if form.is_valid()
            discipline=form.cleaned_data['discipline']
            language=form.cleaned_data['language']
            query = []
            if disciplines:
                query.append(Q(discipline__in=discipline))
            if language:
                query.append(Q(language__in=language))

            if query:    
                tradesman_return=Tradesman.objects.filter(*query)
            else:
                tradesman_return=Tradesman.objects.all()

            #...work with returned data...

注意:GoodPractice(TM) 认为集合使用复数形式(在 Trademan 模型和形式中都应该是“学科”和“语言”。

NB2:惯例是使用 all_lower_with_underscore 名称作为函数,因此您的视图应命名为“trademan_lookup”

于 2013-02-20T12:47:02.257 回答