开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜