0

私は一週間ずっとこれに苦労しており、一度休ませる必要があります. これは多くのコードのように見えるかもしれませんが、核心は単純な概念的な質問です。

次のフィールドを持つモデル UserProfile があります。

user = models.OneToOneField(User)
weekOne = models.OneToOneField(WeekOne)
weekTwo = models.OneToOneField(WeekTwo)

WeekOne と WeekTwo はどちらも、Week というカスタム クラスを継承する独自のフィールド (models.Model) を持つモデルです。Week には、各週のメソッドの再入力を節約するためのいくつかのカスタム関数と、抽象クラスにするための次のコードがあります。

class Meta:
    abstract = True

基本的に、すべてのユーザーに、ユーザー固有の値を持つカスタム フィールドを持つ固有の weekOne および weekTwo (およびそれ以降) のフィールドを持たせたいと考えています。

初めてユーザーを作成するとき (つまり、ユーザーがサインアップするとき) に、次のコードを使用しますviews.py

def signup(request):
    user_form = UserCreateForm(data=request.POST)
    if request.method == 'POST':
        if user_form.is_valid():
            username = user_form.clean_username()
            password = user_form.clean_password2()
            user_form.save()
            user = authenticate(username=username, password=password)
            login(request, user)
            return redirect('/')
        else:
            return index(request, user_form=user_form)
    return redirect('/')

基本的なフォームのサインアップは、ここではすべて正常に機能しています。

さて、ここで物事が危険にさらされます。ユーザーのプロファイルが作成されていることを確認し、作成されていない場合は作成する weekOne のビューがあります。コードは次のとおりです。

@login_required
def workout1(request):
    template = "workout1.html"
    weekOne = WeekOne()
    weekOne.save()
    user, created = UserProfile.objects.get_or_create(user=request.user,
            defaults = {'weekOne': weekOne})
    name = weekOne.__unicode__()

    if created:
        context = {'user': user}
        return render(request, template, context)

    # Grab already existing User Profile
    weekOne.delete() # Was never used
    context = {'user': user, 'name': name}
    return render(request, template, context)

わかった。かっこいいですね。しかし、第 1 週のページに移動しようとすると、次のエラーが表示されます。

workout_game_app_userprofile.weekTwo_id may not be NULL

これは私が迷っているところです。1 週間ごとのビューごとに、1 週間ごとの変数を初期化する必要がありますか? つまり、1 週間目のビューでは、次のようなコードを実行する必要があります。

weekOne = WeekOne()
weekTwo = WeekTwo()
weekThree = WeekThree()

等。?実装を計画している 12 週間すべてを実行しなければならない場合、これはばかげて繰り返されるように思えます。

ところで、私のモデルは、2 週目を実装する前に完全に機能していました。

また、OneToOne は適切な種類のキーを使用するのに適していますか? user.weekOne.item1、user.weekOne.item2 などにアクセスし、そのユーザーだけの値を変更して保存したいです。

UPDATE: Sidharth Shah の場合、私のビューとモデルの残りのコードは次のとおりです。

ビュー.py:

from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.models import User
from workout_game_app.forms import AuthenticateForm, UserCreateForm
from workout_game_app.models import WeekOne, WeekTwo, UserProfile
from django.http import Http404, HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.core import serializers
import simplejson


def index(request, auth_form=None, user_form=None):
    if request.user.is_authenticated():
        user = request.user
        name = "Missions Overview"
        context = {'user': user, 'name': name}
        template = 'workouts.html'
        return render(request, template, context)
    else:
        auth_form = auth_form or AuthenticateForm()
        user_form = user_form or UserCreateForm()
        template = 'index.html'
        context = {'auth_form': auth_form, 'user_form': user_form}
        return render(request, template, context)

def login_view(request):
    if request.method == 'POST':
        form = AuthenticateForm(data=request.POST)
        if form.is_valid():
            login(request, form.get_user())
            return redirect('/')
        else:
            return index(request, auth_form=form)
    return redirect('/')


def signup(request):
    user_form = UserCreateForm(data=request.POST)
    if request.method == 'POST':
        if user_form.is_valid():
            username = user_form.clean_username()
            password = user_form.clean_password2()
            user_form.save()
            user = authenticate(username=username, password=password)
            login(request, user)
            return redirect('/')
        else:
            return index(request, user_form=user_form)
    return redirect('/')

@login_required
def submitWorkout1(request):
    if request.method == 'POST':
        exercise = request.POST['exercise']
        try:
            amount = request.POST['amount']
        except KeyError: # No amount field on form
            amount = ""
        user = UserProfile.objects.get(user=request.user)
        week = user.weekOne
        exercise, amount, exerciseComplete, allComplete = user.updateExercise(week, exercise, amount)
        data = simplejson.dumps({
            'result': 'success',
            'exercise': exercise,
            'amount': amount,
            'exerciseComplete': exerciseComplete,
            'allComplete': allComplete
            }, indent=4)
        return HttpResponse(data)


@login_required
def workout2(request):
    template = "workout2.html"
    weekTwo = WeekTwo()
    weekTwo.save()
    user, created = UserProfile.objects.get_or_create(user=request.user,
            defaults = {'weekTwo': weekTwo})
    name = weekTwo.__unicode__()

    if created:
        context = {'user': user}
        return render(request, template, context)

    # Grab already existing User Profile
    weekTwo.delete() # Was never used
    context = {'user': user, 'name': name}
    return render(request, template, context)

@login_required
def submitWorkout2(request):
    if request.method == 'POST':
        exercise = request.POST['exercise']
        try:
            amount = request.POST['amount']
        except KeyError: # No amount field on form
            amount = ""
        user = UserProfile.objects.get(user=request.user)
        week = user.weekTwo
        exercise, amount, exerciseComplete, allComplete = user.updateExercise(week, exercise, amount)
        data = simplejson.dumps({
            'result': 'success',
            'exercise': exercise,
            'amount': amount,
            'exerciseComplete': exerciseComplete,
            'allComplete': allComplete
            }, indent=4)
        return HttpResponse(data)

そしてmodels.py:

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

class Week(models.Model):
    # List of exercises by name for the week
    exercises = []
    # Week name in unicode
    name = u''

    # Running count of benchmarks met.
    completeCount = models.PositiveSmallIntegerField(default=0)
    # Set to true if benchmarks reached. 
    weekComplete = models.BooleanField(default=False)
        # A bunch of methods

class WeekOne(Week):
    name = u'Mission One'
    exercises = ['squats', 'lunges', 'stairDaysCount', 'skipStairs']
    # Required benchmarks for given exercises
    squatBenchmark = 1000
    lungeBenchmark = 250
    stairDaysCountBenchmark = 3

    totalGoals = 4

    squats = models.PositiveIntegerField(default=0)
    lunges = models.PositiveIntegerField(default=0)
    skipStairs = models.BooleanField(default=False)
    stairDaysCount = models.PositiveSmallIntegerField(default=0)
    # A bunch of methods

class WeekTwo(Week):
    name = u'Mission Two'
    exercises = ['up3Levels', 'noHands', 'treadmill', 'vagMachine', 'extendedStairs']
    totalGoals = 5

    up3Levels = models.BooleanField(default=False)
    noHands = models.BooleanField(default=False)
    treadmill = models.BooleanField(default=False)
    vagMachine = models.BooleanField(default=False)
    extendedStairs = models.BooleanField(default=False)
    # A bunch of methods

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    weekOne = models.OneToOneField(WeekOne, null=True, default=None)
    weekTwo = models.OneToOneField(WeekTwo, null=True, default=None)
    # Some methods

そして、それはうまくいきますが、私のforms.pyは良い尺度です:

from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from django.contrib.auth.models import User
from django import forms
from django.utils.html import strip_tags

class UserCreateForm(UserCreationForm):
    username = forms.CharField(required=True,
            widget = forms.widgets.TextInput(attrs={'placeholder': 'Username'}))
    password1 = forms.CharField(required=True,
            widget = forms.widgets.PasswordInput(attrs={'placeholder': 'Password'}))
    password2 = forms.CharField(required=True,
            widget = forms.widgets.PasswordInput(attrs={'placeholder': 'Password'}))

    def is_valid(self):
        form = super(UserCreateForm, self).is_valid()
        for f, error in self.errors.iteritems():
            if f != '__all_':
                self.fields[f].widget.attrs.update({'class':'error', 'value':strip_tags(error)})
        return form

    class Meta:
        fields = ['username', 'password1', 'password2']
        model = User

class AuthenticateForm(AuthenticationForm):
    username = forms.CharField(
            widget = forms.widgets.TextInput(attrs={'placeholder':'Username'}))
    password2 = forms.CharField(
            widget = forms.widgets.PasswordInput(attrs={'placeholder': 'Password'}))
4

1 に答える 1

1

次のモデルが必要な場合があります

user = models.OneToOneField(User)
weekOne = models.OneToOneField(WeekOne, null=True, default=None)
weekTwo = models.OneToOneField(WeekTwo, null=True, default=None)

それを試してみてください、うまくいくはずです。上記のコードを見ると、weekOne、weekTwo などのフィールドを定義しています。作成中に必要なすべてのフィールド weekOne オブジェクトを割り当てているかどうかはわかりません。

于 2013-03-27T02:06:52.673 に答える