How to create new (unsaved) Django model with associations?
I'm building a开发者_Python百科 "preview" function into the CMS for my website which uses the existing front-end template to render a model. This model has an association:
class FeatureWork(models.Model):
name = models.CharField(max_length=100)
...
class FeatureWorkLink(models.Model):
feature_work = models.ForeignKey(FeatureWork)
In the view for the preview, I'm trying to build the model such that when the template calls feature.featureworklink_set.all it returns the associated links. Since neither model has been saved yet, all the standard Django form techniques seem to go out the window.
This is what I have so far, but it blows up when I call the add method on the manager, since the parent hasn't been saved yet:
form = FeatureWorkAdminForm(initial=request.POST)
featured = form.save(commit=False)
for link in request.POST['links'].split(","):
featured.featureworklink_set.add(FeatureWorkLink(image=link))
Why don't you just add:
preview = BooleanField()
to your models, save everything to database and don't look for hacks. This way you can have drafts for free.
You can actually save it in transaction and rollback when template is ready. It's not very efficient, but at least it will work.
featured.featureworklink_set.add(FeatureWorkLink(image=link))
will immediately attempt to create a relationship between a FeatureWork
and FeatureWorkLink
, which isn't going to happen because that instance of FeatureWork
is not present in the database and you cannot satisfy the predicates for building the foreign key relationship.
But the great thing is that Django's Model
and ModelForm
instances will not validate foreign key relationships until your actually trying to commit the data. So manually constructing your FeaturedWorkLink
with an uncommited, non-existing FeatureWork
should satisfy any presentation of the data you need to do, much to what you'd expect:
links = []
form = FeatureWorkAdminForm(initial=request.POST)
featured = form.save(commit=False)
for link in request.POST['links'].split(","):
links.add(FeatureWorkLink(image=link, feature_work=featured))
# then somewhere in your templates, from the context
{% for link in links %}
<img src="{{ link.image }}"
title="Image for the featured work: '{{ link.feature_work.name }}'" />
{% endfor %}
So basically, during the course of collecting the data to create a FeatureWork
, you'll have to maintain the FeatureWorkLink
instances through subsequent requests. This is where you'd use a model form set, but provide an uncommitted FeatureWork
for the feature_work
property for every model form instance of the set, up until the point where all the data has been collected, where you then provide a commited FeatureWork
instance, so that the model form set can satisfy referential integrity and finally be commited to the database.
精彩评论