如何获取ForeignKey id来创建与模型链接的新表单?

时间:2013-08-17 03:32:31

标签: django django-models django-forms django-views foreign-key-relationship

我很确定这个问题已被涵盖,但我尝试了我在堆栈上找到的所有内容,以解决我的问题而没有任何成功。

这是我的model.py

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


class Description(models.Model):
    titre_routine = models.CharField(max_length=100)
    type_routine = models.CharField(max_length=100)
    lieu_routine = models.CharField(max_length=100)
    periode = models.CharField(max_length=100, blank=True)
    routine_description = models.TextField()
    raison_chgmt = models.TextField(blank=True)
    user = models.ForeignKey(User)
    #prendre une liste de routine et faire une liste de choix
    #si non ajout a la liste de routine dans nouvelle table

    def __unicode__(self):
        return self.titre_routine

#User.profile = property(lambda u: Description.objects.get_or_create(user=u)[0])


class Rewards(models.Model):
    jour = models.CharField(max_length=4)
    activite_altr = models.TextField()
    first_word = models.CharField(max_length=100, blank=True)
    second_word = models.CharField(max_length=100, blank=True)
    third_word = models.CharField(max_length=100, blank=True)
    urge_validator = models.BooleanField() #urge satisfait ou non?
    urge_validate_date = models.DateField(auto_now=True)
    description = models.ForeignKey(Description)

    def __unicode__(self):
        return self.jour

解释我的模型: 一个“用户”可以创建多个“描述”。 “描述”包含多个“奖励”。 ... “描述”包含多个“其他事物”

这是我的view.py

#the user access to his dashboard, dashboard filtered by the user logged in.
@login_required(login_url='/userauth/login/')
def dashboard(request):
    routine_info = Description.objects.filter(user=request.user)
    return render_to_response('dashboard.html', {
        'routine_info': routine_info
    })

#dashboard for the reward section that should be like the first dashboard filtered only by the user logged in AND should only show the reward related to One description created previously by the user.
@login_required(login_url='/userauth/login/')
def reward_dashboard(request):
    reward_info = Rewards.objects.all()
    return render_to_response('rewards_dashboard.html', {
        'reward_info': reward_info
    })


#the user can have access to the reward he created as the other def, he should be the only one to have access (again reward created by the user and related to ONE description)
@login_required(login_url='/userauth/login/')
def reward_description(request, reward_id):
    reward_info = Rewards.objects.get(id=reward_id)
    return render_to_response('reward_description.html', {
        'reward': reward_info
    })

#rewardform, I miss the pieces to obtain de description id that will link both table Rewards and Description (and recursively the User table via Description???)
@login_required(login_url='/userauth/login/')
def new_reward(request):

    if request.POST:
        form = RewardsForm(request.POST)

        if form.is_valid():
            obj = form.save(commit= False)
            obj.description = #Missing piece

            #test that could never happen
            if obj.description == 200:
                return HttpResponseRedirect('/reward_dashboard/')
            else:
                obj.save()

            return HttpResponseRedirect('/reward_dashboard/')

    else:
        form = RewardsForm()

    args = {}
    args.update(csrf(request))

    args['form'] = form

    return render_to_response('create_reward.html', args)

重述:

- 用户可以访问他创建的奖励,因为另一个def应该是唯一可以访问的人(再次由用户创建并与一个描述相关的奖励)

- 奖励部分的控制台应该是第一个仪表板仅由登录的用户过滤而且应该只显示与之前创建的奖励相关的一个描述。

-rewardform,我错过了获取de description id的部分,它将链接表奖励和描述(并通过描述递归User表)

我应该尝试调查会话吗? (当用户创建描述时,我为他指定了一个特定的ID?)

我希望我在解释中明白我的情况。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您有多种选择来解决这个问题。这实际上取决于您希望在应用中实施的工作流程。

在创建奖励之前选择说明

您将有一个列出所有用户说明的页面:这是您的信息中心视图。 从这里开始,用户必须选择他想要添加奖励的描述:点击它,点击特定的创建奖励链接等。这取决于你(ergo /设计选择)。重点是获取描述 id 并通过URLconf(new_reward)将其传递到您的urls.py视图,其中包含以下内容:

# urls.py
urlpatterns = patterns('',
  # your urlpatterns ...
  url(r'^description/(?P<description_id>\d+)/reward/add/$', 'your.app.views.new_reward', name='add-reward'),
  # your urlpatterns ...
)

这只是一个例子。您可以根据需要设置URL。无论如何,当您的用户点击链接或按钮(或您选择的任何内容)时,URL将类似于 mondomaine.fr/yourappprefix/description/4/reward/add (其中4是所选描述的ID - 由您来生成这样的链接)

在您的视图中,您可以检索描述对象:

#rewardform, I miss the pieces to obtain de description id that will link both table Rewards and Description (and recursively the User table via Description???)
@login_required(login_url='/userauth/login/')
def new_reward(request, description_id):
    description = Description.objects.get_or_404(id=description_id)
    pass

使用直接链接创建奖励

如果这种工作流程在您的案例中甚至不是一个选项,那么请向您的RewardsForm添加一个描述字段。有了这个,您的用户将能够瞄准他想要添加奖励的描述。

要将描述列表限制为仅由当前用户创建的列表,您可以在views.py中执行此操作:

# your code ...
else:
    form = RewardsForm()
    form.fields['description'].queryset = Description.objects.filter(user=request.user)

如果form.is_valid返回False,则可能需要进行保存。

我希望至少可以帮助你。

答案 1 :(得分:0)

在我的models.py中 我只添加了一个ForeignKey来链接我的另一个表(Rewards to User),以便能够获取当前登录用户的当前id(以限制不属于用户的描述)

user = models.ForeignKey(User)   

在我的urls.py

url(r'^reward_dashboard/(?P<routine_id>\d+)/$', reward_dashboard),
url(r'^reward_create/(?P<description_id>\d+)/$', new_reward),
url(r'^reward_description/(?P<reward_id>\d+)/$', reward_description),

在我的views.py中:

@login_required(login_url='/userauth/login/')
def reward_dashboard(request, routine_id):    (get the routine_id to only get the dashboard related to the description)
    d = Description.objects.get(id=routine_id) #give the object with description related)
    reward_info = Rewards.objects.filter(user=request.user).filter(description=d) #filter with the right description (from the routine_id passed in) and the right user logged.
    return render_to_response('rewards_dashboard.html', {
        'reward_info': reward_info,
        'd' : d      #i will in my template render the d.id in a link {{reward_id}}
    })


@login_required(login_url='/userauth/login/')
def reward_description(request, reward_id):
    reward_info = Rewards.objects.filter(user=request.user).get(id=reward_id)
    return render_to_response('reward_description.html', {
        'reward': reward_info
    })

@login_required(login_url='/userauth/login/')
def new_reward(request, description_id):
    #description = Description.objects.get_or_404(id=description_id)

    d = Description.objects.get(id=description_id) #get all object with the description_id
    if request.POST:
        form = RewardsForm(request.POST)

        if form.is_valid():
            obj = form.save(commit= False)
            obj.description = d #fill the form with the id that come from my template link
            obj.user = request.user #fill the user with the logged one

            if obj.description == 200:
                return HttpResponseRedirect('/dashboard/')
            else:
                obj.save()

            return HttpResponseRedirect("/reward_dashboard/%s" % d.id)

    else:
        form = RewardsForm()



    args = {}
    args.update(csrf(request))

    args['form'] = form
    args['d'] = d 

    return render_to_response('create_reward.html', args)

我希望我的解释会有所帮助。

ps:我将看看get_or_404()以了解它是如何工作的,因为现在我现在看不到结果的差异,但是确保重定向试图访问的用户会很有趣不属于。