2014-09-19 36 views
1

我有一个1:在两个模型类在我的Django应用一对多的关系:如何创建自定义的外国套Django模型

class CheckList(models.Model): 
    user = models.ForeignKey(User, related_name='checklists') 
    name = models.CharField(max_length=50) 

class CheckListItem(models.Model): 
    user = models.ForeignKey(User, related_name='items') 
    checklist = models.ForeignKey(WishList, related_name='items') 
    is_checked = models.BooleanField(default=False) 

大部分的时间,我想提出一个用户的清单以及每个清单的物品,而且非常香草。

但是,我也想要一些包含自定义列表项目的“虚拟清单”。

我想做到这一点:

def get_checklist_checked(user): 
    checklist = CheckList(name='My Checked Items', user=user) 
    checklist.items = CheckListItem.objects.filter(user=user, check=True) 
    return checklist 

当然现在,checklist.items是一个数组,而通常checklist.items是一个经理。

处理这种情况的正确方法是什么?

+0

你想在list.items被调用时返回对象的相关列表项吗?另外,请使用比'list'更好的变量。 – karthikr 2014-09-19 13:59:08

+0

为了说明的目的,我使用泛型,但我可以看到它如何变得混乱。大多数时候,list.items检索相关项目(基于FK关系),但是我希望能够构建临时的'list'对象(它们本身不在数据库中)。一个例子中的“list”对象将包含所有具有“check = True”的项目。 – ryansilva 2014-09-19 14:05:02

+0

你有没有考虑过使用“自定义管理器”? – karthikr 2014-09-19 14:20:30

回答

0

我学到了更多关于custom managers的内容,我理解我如何使用自定义管理器来预定义查询。

但是,我实质上只是在CheckList类的某些情况下要求更改用于CheckListItem的相关访问的管理器,并且我认为这不可能。

我的决定是因为我已经有一套DTO方法将模型转换为字典(因为这些方法直接进入JSON响应),所以我暂时不会使用CheckList类来执行瞬态校验列表。相反,我会直接获取过滤项目,并编写DTO方法来接受CheckList对象或清单名称和项目。

def get_checklist(request, checklist_id): 
    #get a special 'transient' checklist 
    if checklist_id == 'checkedItems': 
     items = CheckListItem.objects.filter(is_checked=True) 
     dto = getCheckListDto(items=items, name="Checked Items") 
    #get a regular checklist 
    else: 
     cl = CheckList.objects.get(checklist_id) 
     dto = getCheckListDto(checklist=cl) 

    return HttpResponse(json.dumps(dto), content_type="application/json") 

#Can pass in either a checklist object, or name + items array 
def getCheckListDto(checklist=None, items=[], name=None): 
    if checklist is not None: 
     items = checklist.items.all() 
     name = checklist.name 

    return { 
     'name': name, 
     'items': [getCheckListItemDto(i) for i in items] 
    } 

在那里我可以看到使用自定义的经理将提供一个经理只获取is_checked检查单项目,这样我可以只是做CheckListItem.checked_objects.all()唯一的地方。但由于过滤器非常简单,所以我没有打扰。

如果有人有更好的主意,特别是如果我错过了定制经理可以帮助的方式,请随时提交答案。