不能分配必须是实例。姜戈

Posted

技术标签:

【中文标题】不能分配必须是实例。姜戈【英文标题】:Cannot assign must be a instance. Django 【发布时间】:2012-05-19 02:53:08 【问题描述】:

我一直在尝试创建一个拥有用户的 django 项目,这些用户可以添加他们创建的书籍的标题。但是每次我输入书名(不在管理页面上)时都会出现此错误

Cannot assign "u'Hello Wold'": "Scripter.title" must be a "Book" instance.

models.py

from django.db import models
from django.contrib.auth.models import User

class Book(models.Model):
    script_title = models.CharField(max_length=100)

    def __unicode__(self):
        return self.script_title

class Scripter(models.Model):
    user = models.OneToOneField(User)
    name = models.CharField(max_length=30)
    title = models.ForeignKey(Book, null=True, blank=True, default=None)

    def __unicode__(self):
        return self.name

forms.py

from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
from scripters.models import Scripter#, Book

class RegistrationForm(ModelForm):
    username = forms.CharField(label=(u'User Name'))
    email = forms.EmailField(label=(u'Email Address'))
    password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))
    password1 = forms.CharField(label=(u'Verify Password'), widget=forms.PasswordInput(render_value=False))

    class Meta:
        model = Scripter
        exclude = ('user','title')

    def clean_username(self):
        username = self.cleaned_data['username']
        try:
            User.objects.get(username=username)
        except User.DoesNotExist:
            return username
        raise forms.ValidationError("User Name has been taken!")

    def clean(self):
        if self.cleaned_data['password'] != self.cleaned_data['password1']:
            raise forms.ValidationError("The passwords did not match")
        else:
            return self.cleaned_data

class LoginForm(forms.Form):
    username = forms.CharField(label=(u'Username'))
    password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))

class CreateScript(ModelForm):
    title = forms.CharField(label=(u'Script Title'))

    class Meta:
        model = Scripter
        exclude = ('user','name',)

    def clean_title(self):
        title = self.cleaned_data['title']
        return title

views.py

from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.shortcuts import render_to_response
from django.template import RequestContext
from scripters.forms import RegistrationForm, LoginForm, CreateScript
from scripters.models import Scripter, Book
from django.contrib.auth import authenticate, login, logout

def ScripterRegistration(request):
    if request.user.is_authenticated():
        return HttpResponseRedirect('/profile/')
    if request.method =='POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            user = User.objects.create_user(username=form.cleaned_data['username'],
                email = form.cleaned_data['email'],
                password = form.cleaned_data['password']
            )
            user.save()
            scripter = Scripter(user=user, name=form.cleaned_data['name'])
            scripter.save()

            return HttpResponseRedirect('/profile/')
        else:
            return render_to_response('index.html', 'form': form, context_instance=RequestContext(request))
    else:
        form = RegistrationForm()
        context = 'form': form
        return render_to_response('index.html', context, context_instance=RequestContext(request))

@login_required
def Profile(request):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/login/')
    Scripter = request.user.get_profile()

    context = 'Scripter': Scripter, 'Book': Book
    return render_to_response('profile.html', context, context_instance=RequestContext(request))

def LoginRequest(request):
    if request.user.is_authenticated():
        return HttpResponseRedirect('/profile/')
    if request.method == 'POST':
        submit = LoginForm(request.POST)
        if submit.is_valid():
            username = submit.cleaned_data['username']
            password = submit.cleaned_data['password']
            scripter = authenticate(username=username, password=password)
            if scripter is not None:
                login(request, scripter)
                return HttpResponseRedirect('/profile/')
            else:
                return HttpResponseRedirect('/login/')
    else:
        submit = LoginForm()
        context = 'submit': submit
        return render_to_response('login.html',context, context_instance=RequestContext(request))

def LogoutRequest(request):
    logout(request)
    return HttpResponseRedirect('/login/')

@login_required
def NewScript(request):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/login/')
    if request.method =='POST':
        title_form = CreateScript(request.POST)
        if title_form.is_valid():
            new_script = Book.objects.get_or_create(
                script_title = title_form.cleaned_data['title']
            )
            new_script.save()
            script = Book(script_title=title_form.cleaned_data['title'])
            script.save()
            return HttpResponseRedirect('/edit/')
        else:
            return render_to_response('NewScript.html', 'title_form': title_form, context_instance=RequestContext(request))
    else:
        title_form = CreateScript()
        context = 'title_form': title_form
        return render_to_response('NewScript.html', context, context_instance=RequestContext(request))

【问题讨论】:

【参考方案1】:

当然。不知道这里的混乱在哪里。 Scripter.titleBook 的外键,所以你必须给它一个实际的 Book,而不是字符串。

【讨论】:

【参考方案2】:

首先,虽然这不是你的问题,但我相信你错过了一些东西。如果我理解正确,您希望 Scripters 拥有 MULTIPLE 书籍。现在,对于您的模型,他们只能拥有一本书。如果我对您想要实现的目标是正确的,那么您的模型应该看起来像这样:

class Book(models.Model):
  script_title = models.CharField(max_length=100)
  scripter = models.ForeignKey(Scripter)#A book "remembers" who wrote it

  def __unicode__(self):
    return self.script_title

class Scripter(models.Model):
  user = models.OneToOneField(User)
  name = models.CharField(max_length=30)
  #Scripter can write multiple books, can't he? So the next line is removed,
  #replaced by an extra line in Book class

  # title = models.ForeignKey(Book, null=True, blank=True, default=None)

然后你会像这样访问 Scripter 的书:

scripter = Scripter.objects.get(name="joshua")
books = scripter.book_set.all() #all books written by joshua

至于你的问题,以目前的形式,你需要做这样的事情:

book = Book.objects.get(script_title="some_title")
scripter.title = book

但正如我之前所说,你需要改变你的模型结构,所以你宁愿这样做:

scripter = Scripter.objects.get(name="joshua")
book = Book.objects.Create(script_title="some title",scripter=scripter)

【讨论】:

【参考方案3】:

您的图书模型中没有主键

    class Book(models.Model):
script_title = models.CharField(primary_key = True,max_length=100)

def __unicode__(self):
    return self.script_title

这应该可以工作

【讨论】:

以上是关于不能分配必须是实例。姜戈的主要内容,如果未能解决你的问题,请参考以下文章

Django错误。插入表时不能分配必须是实例

Java中抽象类和接口中均不能定义静态的抽象方法

您是不是忘记注册或加载此标签?姜戈

pytorch posix memalign分配内存不能用

如何在 div 的 html 背景 url 中使用产品图片?姜戈

设计者必须创建一个...不能的实例,因为该类型被声明为抽象