English 中文(简体)
Why do I need to save this model before adding it to another one?
原标题:

In django, I m trying to do something like this:

# if form is valid ...
article = form.save(commit=False)
article.author = req.user

product_name = form.cleaned_data[ product_name ]
try:
    article.product = Component.objects.get(name=product_name)
except:
    article.product = Component(name=product_name)

article.save()
# do some more form processing ...

But then it tells me:

null value in column "product_id" violates not-null constraint

But I don t understand why this is a problem. When article.save() is called, it should be able the create the product then (and generate an id).

I can get around this problem by using this code in the except block:

product = Component(name=product_name)
product.save()
article.product = product

But the reason this concerns me is because if article.save() fails, it will already have created a new component/product. I want them to succeed or fail together.

Is there a nice way to get around this?

最佳回答

You could get around this by using :

target_product, created_flag = Component.objects.get_or_create(name=product_name)
article.product = target_product

as I m pretty sure get_or_create() will set the id of an object, if it has to create one.

Alternatively, if you don t mind empty FK relations on the Article table, you could add null=True to the definition.

问题回答

The way the Django ManyToManyField works is that it creates an extra table. So say you have two models, ModelA and ModelB. If you did...

ModelA.model_b = models.ManyToManyField(ModelB)

What Django actually does behind the scenes is it creates a table... app_modela_modelb with three columns: id, model_a_id, model_b_id.

Hold that thought in your mind. Regarding the saving of ModelB, Django does not assign it an ID until it s saved. You could technically manually assign it an ID and avoid this problem. It seems you re letting django handle that which is perfectly acceptable.

Django has a problem then doing the M2M. Why? If ModelB doesn t have an id yet, what goes in the model_b_id column on the M2M table? The error for null product_id is more than likely a null constraint error on the M2M field, not the ModelB record id.

If you would like them to "succeed together" or "fail together" perhaps it s time to look into transactions. You, for example, wrap the whole thing in a transaction, and do a rollback in the case of a partial failure. I haven t done a whole lot of work personally in this area so hopefully someone else will be of assistance on that topic.

There s little value in including a code snippet on transactions, as you should read the Django documentation to gain a good understanding.





相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签