2012-05-10 20 views
10

He estado tratando de crear un proyecto django que tenga usuarios y esos usuarios puedan agregar títulos de libros que hayan creado. Pero cada vez que introduzca un título del libro (no en la página de administración) me sale este errorNo se puede asignar debe ser una instancia. 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)) 

Respuesta

11

Por supuesto. No estoy seguro de dónde está la confusión aquí. Scripter.title es una clave externa a Book, por lo que debe darle un Book real, no una cadena.

5

Primero, aunque esta no es su pregunta, creo que se ha perdido algo. Si entiendo correctamente, desea que los Scripters tengan MÚLTIPLES libros. Ahora, con tus modelos, solo pueden tener un libro. Si estoy en lo correcto a partir de lo que está tratando de lograr, su modelo más bien debería tener este aspecto:

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) 

allí tendría que tener acceso a los libros de Scripter así:

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

cuanto a su pregunta, en su forma actual, que tendría que hacer algo como esto:

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

Pero como he dicho antes, es necesario cambiar la estructura del modelo, por lo que será más bien haciendo:

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