0

在我看来,我正在研究 Django 中的一些有趣的问题:模型继承及其在模板中的行为。为了清楚起见,我是一个 django 菜鸟,所以这可能根本不是问题,实际上:)

他是我在模型中所拥有的:

模型.py

class AbstractUserProfile(models.Model):
    user = models.OneToOneField(User,
                                null=False, blank=False,
                                related_name=u'user_link')


    class Meta:
        abstract = True 

class UserProfile(AbstractUserProfile):

    personal_page = models.URLField(null=True, blank=True,
                                    verbose_name=u'personal page url')

    site_url = models.CharField(max_length=100,
                                null=False, blank=False,
                                unique=True,
                                verbose_name=u'web-site url')

    photo = ImageField(upload_to=u'profiles',
                       null=True, blank=True,
                       verbose_name=u'Profile picture')

以及同一个 models.py 文件中的另外两个类:

class ProfileTypeOne(UserProfile):
    status = models.TextField(blank=True)

    def get_status(self):
         return mark_safe(self.status)

class ProfileTypeTwo(UserProfile):
    interests = models.TextField(blank=True)

    def get_status(self):
         return mark_safe(self.interests)

在模板中我有一些代码,需要调用ProfileType特定的方法,比如

.... some html .... {{ user.user_link.get_status }} ... some more html ....

O 确实知道模型继承中自动创建的 OneToOneRelationship,并且我可以通过这种方式访问​​所需的方法:

{{ user.user_link.profiletypeone.get_status }}

唯一的问题是,我在模板渲染的某些时候不知道配置文件类型。在不引发 ProfileTypeOne.DoesNotExist 异常的情况下,解决此问题的最佳方法是什么:

  1. 将此逻辑转移到视图中并创建一些标志,然后在模板中检查它并访问受尊重的子类?
  2. 处理模板中的 DoesNotExist 异常?(不知道怎么做)
  3. 在模板中使用这种冗余的低效结构(几乎是变体#2):

{{ user.user_link.profiletypeone.get_status }}{{ user.user_link.profiletypetwo.get_status }}

我之所以要将此逻辑放入模板中,是因为该模板将被多次扩展,并且此基本逻辑应该在所有模板中,因此迫使我,在将逻辑转移到视图部分的情况下,多次调用某些代码,而不是一个。

提前致谢!

4

1 回答 1

1

那么我的偏好是在视图中而不是在模板中进行错误处理。有很多方法可以做到这一点,下面是一个简单的例子。

###helpers.py
import models

def get_profile1_or_profile2(user):
    profile = get_instance_or_none(models.ProfileTypeOne, user=user)
    if profile is None:
        profile = get_instance_or_none(models.ProfileTypeTwo, user=user)
    return profile

def get_instance_or_none(model, **kwargs):
    try:
        result = model.objects.get(**kwargs)
    except:
        result = None
    return result


###views.py
import helpers

def some_view(request):
    """
    This view renders some template.
    """

    profile = helpers.get_profile1_or_profile2(request.user)
    if profile:
        # Render the template and pass in the profile object
    else:
        # Redirect to 404 or whatever kind of error handling.

然后在你的模板中你可以简单地做{{ profile.get_status }}

也如你所说:

我之所以要将此逻辑放入模板中,是因为该模板将被多次扩展,并且此基本逻辑应该在所有模板中,因此迫使我,在将逻辑转移到视图部分的情况下,多次调用某些代码,而不是一个。

如何将逻辑转移到视图,多次调用代码。我的意思是这取决于您提出的请求,无论您的代码位于模板还是视图中。这就是请求在这两种情况下的工作方式。

在视图的情况下:

提出请求 --> Url 向视图发送请求 --> 代码在此处运行 --> 呈现模板

如果是模板:

提出请求 --> Url 向视图发送请求 --> 视图呈现模板 --> 代码在此处运行

于 2013-03-20T08:01:22.340 回答