【问题标题】:Django: Attribute error on custom Save()Django:自定义 Save() 上的属性错误
【发布时间】:2016-05-21 14:45:56
【问题描述】:

我在为下面的 protocol 模型创建自定义 slug 时遇到问题。用于创建 slug 的自定义保存功能在我在管理页面中可以正常工作,但当我使用下面的 add_protocol 视图时却不行。 Study 模型有一个名为 protocolnumber 的字段,所以我不确定它为什么认为它没有。

我认为这与视图的设置方式有关,即commit = false,然后是commit=true。可能是因为在 commit = False 上,它试图在分配之前使用来自 study 模型的信息来分配 slug 值。不知道如何解决这个问题。谢谢!

模型:

class Study(models.Model):
        protocolnumber = models.CharField(max_length=100, blank=True, null=True)


class Protocol(models.Model):
    study = models.ForeignKey(Study, null=True)
    version = models.DecimalField(max_digits=3, decimal_places=1, null=True)
    slug = models.SlugField(max_length=200, blank=True, null=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.study.protocolnumber)+'-V'+slugify(self.version)
            super(Protocol, self).save(*args, **kwargs)

观点:

def add_protocol(request,  study_slug):
    study = get_object_or_404(Study, slug=study_slug)
    if request.method == 'POST':
        new_protocol = AddProtocol(request.POST, request.FILES)
        if new_protocol.is_valid():
            new_protocol.save(commit=False)
            new_protocol.study = study
            new_protocol.save()
            return HttpResponseRedirect(reverse('studies:studydetails', args=(study.slug,)))
        else:
            HttpResponse('Something is messed up')
    else:
        new_protocol = AddProtocol()
        return render(request, 'studies/addprotocol.html', {'new_protocol': new_protocol, 'study': study})

错误:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/studies/lilly-a4/add-protocol/

Django Version: 1.8.7
Python Version: 3.5.0
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'studies',
 'account')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')


Traceback:
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/RickyD/PycharmProjects/StudyTrack/studies/views.py" in add_protocol
  112.             new_protocol.save()
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/forms/models.py" in save
  459.                              construct=False)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/forms/models.py" in save_instance
  105.         instance.save()
File "/Users/RickyD/PycharmProjects/StudyTrack/studies/models.py" in save
  92.             self.slug = slugify(study.protocolnumber)+'-V'+slugify(self.version)

Exception Type: AttributeError at /studies/lilly-a4/add-protocol/
Exception Value: 'NoneType' object has no attribute 'protocolnumber'

【问题讨论】:

  • self.study 为无时会发生这种情况。你需要优雅地处理它
  • 好吧,我的建议可能不一定正确,因为我不了解您的业务规则。但是如果一个协议需要有一项与之相关的研究,那么研究应该是一个必填字段。

标签: django pycharm slug overriding


【解决方案1】:

您允许 study ForeignKey 为 NULL,所以就像 @karthikr 所说,您需要优雅地处理这个问题。一种方法是:

class Protocol(models.Model):
    study = models.ForeignKey(Study, null=True)
    version = models.DecimalField(max_digits=3, decimal_places=1, null=True)
    slug = models.SlugField(max_length=200, blank=True, null=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            protocolnumber = self.study.protocolnumber if self.study else ""
            self.slug = slugify(protocolnumber)+'-V'+slugify(self.version)
            super(Protocol, self).save(*args, **kwargs)

【讨论】:

  • 所以这很有意义。然后我的问题是在视图的开头我调用study = get_object_or_404(Study, slug=study_slug) 不应该确保我有study 对象而不是none
猜你喜欢
  • 2018-11-21
  • 1970-01-01
  • 2020-11-25
  • 2018-05-18
  • 1970-01-01
  • 1970-01-01
  • 2020-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多