【问题标题】:Django models and viewsDjango 模型和视图
【发布时间】:2015-09-23 15:54:19
【问题描述】:

我正在尝试创建我的第一个项目。就像 Stack Overflow 关于特定主题的问题和答案。我通过 AbstractBaseUser 创建自己的用户。现在我想创建问答模型。

我的模特:

class Question(models.Model):

text = models.TextField()
title = models.CharField(max_length=200)
date = models.DateTimeField(default=datetime.datetime.now)
author = models.ForeignKey(CustomUser)
def __str__(self):
    return self.title

类答案(models.Model):

text = models.TextField()
date = models.DateTimeField(default=datetime.datetime.now)
likes = models.IntegerField(default=0)
author = models.ForeignKey(CustomUser)
question = models.ForeignKey(Question)

类标签(models.Model):

TYPE_OF_TAGS = (
    ('First tag', 'First'),
    ('Second tag', 'Second'),
    ('Third tag', 'Third'),
    )
type_of_tag = models.CharField(max_length=12, choices=TYPE_OF_TAGS, blank=True)
question = models.ManyToManyField(Question)

我的观点:

def question(request):

args = {}
args.update(csrf(request))
args['form'] = QuestionForm()
args['profile'] = CustomUser.objects.filter(pk = request.user.pk)
args['author'] = Question()

if request.POST:
    args['form'] = QuestionForm(request.POST)
    obj = args['form'].save(commit=False)
    obj.save()
    args['author'].author = args['profile']
    args['author'].save()
    return redirect(reverse(question))

return render(request, 'questions.html', args)

我为答案创建了第一个视图,发送表单时出现错误:

“author_id”列中的空值违反非空约束

我想我走错了方向。我有不好的模型和不好的观点。为什么我有这个错误,我的模型有什么问题?

【问题讨论】:

  • 在创建问题之前,您需要创建作者并关联到表单问题。

标签: python django


【解决方案1】:

如果您的业务规则不允许问题的作者为空,则必须在保存之前将作者值设置为您的 obj。 比如:

def question(request):

    args = {}
    args.update(csrf(request))
    args['form'] = QuestionForm()
    args['profile'] = CustomUser.objects.filter(pk = request.user.pk)

    if request.POST:
        args['form'] = QuestionForm(request.POST)
        obj = args['form'].save(commit=False)
        obj.author = args['profile']
        obj.save()
        return redirect('your_redirect_url')

    return render(request, 'questions.html', args)

您还有另一个选择: 您可以将以下初始字典传递给 QuestionForm:

{
    'author' : CustomUser.objects.filter(pk = request.user.pk)
}

类似:

def question(request):

    args = {}
    args.update(csrf(request))
    args['form'] = QuestionForm(initial={
        'author': CustomUser.objects.filter(pk = request.user.pk)    
    })

    if request.POST:
        args['form'] = QuestionForm(request.POST)
        obj = args['form'].save()
        return redirect('your_redirect_url')

    return render(request, 'questions.html', args)

注意:在您的 questions.html 模板中呈现作者值的隐藏字段非常重要,因此它包含在 POST 数据中。

【讨论】:

  • 感谢像你这样的人。我可以教 Django 开发!
  • 我认为你的模型是对的。我唯一不同的是把 ManyToMany 字段放在 Question 模型中,而不是 Tag (我认为最好用单数命名模型)。意思是完全一样的,但是说“A question has tags”比说“A tag has questions”更自然。此外,如果您使 Tag 模型独立于 Question 模型,您还可以在 Answer 模型中为 Tag 放置一个 ManyToMany 字段,也可以“标记”答案。
  • 太棒了!非常感谢您的详细回答
  • 我认为最有用的方法是让用户键入一个字符串列表(可能是逗号分隔)。在表单中,创建一个 clean_tags(假设您的表单字段名为“tags”)来处理该大字符串,并将其拆分为候选标签。对于每一个,找出具有相同内容的标签是否已经存在(如果存在,则使用它)并为不存在的字符串创建新标签。
  • 如果您还添加了一个提前输入功能来查询数据库以查找匹配的标签,同时用户正在输入并允许他选择其中一个结果,则更容易使用,并避免人们创建与现有标签等效的新标签。
【解决方案2】:

外键字段使用null = True,可以为空。

class Question(models.Model):

    #...
    author = models.ForeignKey(CustomUser, null = True, blank = True)

否则,在首先保存模型时指定作者的值,这是您错误的做法。我无法理解args['author'] = Question() 是什么意思?你应该做一些事情

args['author'] = CustomUser() # in your question view

改为。

【讨论】:

  • 谢谢。我在视图中更改了我的模型和这条线args['profile'] = CustomUser.objects.get(pk = request.user.pk) 当我发送表单时,字段 Question.author 是 None
  • 更改模型,不是正确的解决方案,因为我认为问题,必须有作者。
  • 然后指定作者,正如我在“其他”部分中提到的那样
猜你喜欢
  • 1970-01-01
  • 2018-04-05
  • 2015-03-16
  • 2016-04-27
  • 1970-01-01
  • 2016-11-01
  • 2013-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多