2011-11-01 31 views
2

我跟随Beginning Django E-Commerce,但我发现有关用户配置文件的部分有点令人困惑。基本上,我有一个抽象类是这样的:Django用户配置文件中的必填字段

class BaseOrderInfo(models.Model): 
    class Meta: 
    abstract = True 
    # a bunch of fields follow 
    shipping_name = models.CharField() 
    # etc 

此之后,用户配置类继承BaseOrderInfo:

class UserProfile(BaseOrderInfo): 
    user = models.ForeignKey(User, unique = True) 
    # Possibly other methods or fields here 

最后,有一个检索方法,正如它的名字所暗示的,检索用户配置文件(如果该用户配置文件不存在,它会创建一个针对该用户对象):

def retrieve(request): 
    try: 
    profile = request.user.get_profile() 
    except UserProfile.DoesNotExist: 
    profile = UserProfile(user=request.user) 
    profile.save() 
    return profile 

好吧,我的问题是:怎么可能保存该用户配置instanc e在检索方法中,只需添加一个User实例,因为UserProfile从BaseOrderInfo类继承了相当多的其他字段?据我所知,Model和ModelForm默认创建必需的字段。

感谢

回答

1

保存表单时,Django不验证模型。 (请参阅Validating Objects上的文档)。如果您在保存之前明确地呼叫profile.full_clean(),那么您将看到验证错误。

如果没有指定所需的外键,那么您将得到一个数据库IntegrityError。其他必填字段由Django进行验证,而不是数据库。如果Django不验证模型,那么在将数据库中的空字符串保存到CharField时不会有任何错误。

+0

哦,现在我明白了。 save()不会调用full_clean()。但是,https://docs.djangoproject。com/en/dev/ref/models/instances /#当你保存时发生什么 - 描述了保存的过程,并指出了4和5看起来应该在将SQL语句插入数据库之前进行验证。你能澄清那部分吗? –

+0

预处理和准备与验证不同,尽管它们可能引发验证错误,例如@Chris建议将'datetime'空。当'UserProfile'实例中的CharField被要求为数据库准备值时,它会返回默认的'u'“'。它没有被要求验证价值。 – Alasdair

+0

太好了。非常感谢。 –

1

如果UserProfile有任何必填字段,你需要展示一个形式向用户首先收集数据。只要您需要访问用户个人资料数据,但确定个人资料尚不存在,您可以将其整合到您的注册表单中,或者仅提供一份单独的个人资料表。

+0

感谢您的回答。在这种情况下,我写了书中的类。 UserProfile没有任何更多的字段,但是,BaseOrderInfo有相当多的字段。作为models.Model的子类中的字段默认是必需的,BaseOrderInfo不包含任何使用“required = False”的字段,在我看来,profile.save()不应该工作。 –

+0

似乎你不了解继承。 'BaseOrderInfo'是一个抽象类;它本身并不存在,而只是提供一个模板。当你让'UserProfile'继承它时,'UserProfile'包含所有这些字段,就像你简单地把它们放在'UserProfile'类本身一样。相同的说明适用。如果有必填字段,则必须提供用于输入该数据的表单。 –

+0

也许我没有正确表达自己。我理解继承部分,但我想知道为什么在保存UserProfile的实例时为什么从BaseOrderInfo继承的UserProfile字段被'忽略',假设默认情况下这些字段是必需的。我认为@Alasdair指出解决方案:save()不验证。 –

相关问题