简体   繁体   中英

Django how to pass foreign key into ModelForm field

I am new to Django and as a learning project I am building a to do list app. The main page (lists.html) displays List objects and Item objects (related via foreign Key).

Lists.html displays all Lists and any Items on those lists. Next to the List title, the is a "New" link. Clicking this link takes you to create.html where you can create new Items and add them to Lists. What I want to happen is when you click "New" it takes you to create.html but it has pre-populated the todo_list foreign key field depending on which List you clicked "New" next to.

My initial strategy was to try and pass the List ID into the URL, but then I struggled getting that into the todo_list foreign key field. Is this the right approach? What other ways can this be achieved?

Code below, thanks in advance.

models.py:

from django.db import models
from django.forms import ModelForm
import datetime

PRIORITY_CHOICES = (
    (1,'Low'),
    (2,'Normal'),
    (3,'High'),
)
# Create your models here.
class List(models.Model):
    title = models.CharField(max_length=250,unique=True)

    def __str__(self):
        return self.title
    class Meta:
        ordering = ['title']
    class Admin:
        pass

class Item(models.Model):
    title = models.CharField(max_length=250)
    created_date = models.DateTimeField(default=datetime.datetime.now)
    priority = models.IntegerField(choices=PRIORITY_CHOICES,default=2)
    completed = models.BooleanField(default=False)
    todo_list = models.ForeignKey(List)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['-priority','title']

    class Admin:
        pass

class NewItem(ModelForm):
   class Meta:
       model = Item
       fields = ['title','priority','completed','todo_list']

views.py:

from django.shortcuts import render_to_response
from django.shortcuts import render
from todo.models import List
from todo.models import Item
from todo.models import NewItem
from django.http import HttpResponseRedirect
# Create your views here.
def status_report(request):
    todo_listing = []
    for todo_list in List.objects.all():
        todo_dict = {}
        todo_dict['id'] = id
        todo_dict['list_object'] = todo_list
        todo_dict['item_count'] = todo_list.item_set.count()
        todo_dict['items_complete'] = todo_list.item_set.filter(completed=True).count()
        todo_dict['percent_complete'] =int(float(todo_dict['items_complete'])/todo_dict['item_count']*100)
        todo_listing.append(todo_dict)
    return render_to_response('status_report.html', {'todo_listing': todo_listing})

def lists(request):
    todo_listing = []
    for todo_list in List.objects.all():
        todo_dict = {}
        todo_dict['list_object'] = todo_list
        todo_dict['items'] = todo_list.item_set.all()
        todo_listing.append(todo_dict)
    return render_to_response('lists.html',{'todo_listing': todo_listing})

def create(request):
    if request.method == 'POST':
        form = NewItem(request.POST or None)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/lists/')
    else:
        form = NewItem()

    return render(request, 'create.html', {'form': form})

lists.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>To-do List Status Report</title>

  </head>

  <body>

    <h1>To-do lists</h1>

{% for list_dict in todo_listing %}

    <h2>{{ list_dict.list_object.title }} <a href='/create/'>New</a></h2>
    <table>
    {% for item in list_dict.items %}


    <tr><td>{{ item }}</td><td><a href='/delete/{{item.id}}/'>Del</a></td></tr>

    {% endfor %}
    </table>



    </ul>

{% endfor %}

  </body>

</html>

create.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>Create Task</title> 
</head>

  <body>
        <form action="/create/" method="post">
            {% csrf_token %}
            {% for field in form %}<p>{{field}}</p>{% endfor %}
            <input type="submit" value="Submit" />
        </form>

  </body>

</html>

Maybe this could help: https://stackoverflow.com/a/5470037/2002580

You Want to get some data passed up with the request. I think something like the the URL scheme might be useful since it's not going to be crazy complex.

# urls.py
urlpatterns += patterns('myview.views',
    url(r'^(?P<user>\w+)/', 'myview', name='myurl'), # I can't think of a better name
)

# template.html
<form name="form" method="post" action="{% url myurl username %}">

# above code is from the linked answer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM