In my Django model I have two fields, name
(a regular CharField
) and slug
, a custom field that generates the slug based on a field name passed in the field definition, in this case I use name
for this.
First, the model only had the name
field, with it's corresponding migrations and all. Then I needed to add the slug
field, so following South conventions, I added the slug field with unique=False
, create the schema migration, then created a data migration, set the unique=True
and create another migration for this last change.
Since the value of the slug is generated on model save, in the forwards
method of the data migration what I did was to iterate over the queryset returned by orm['myapp.MyModel'].objects.all()
and calling the save()
method on each instance.
But the value of the slug field is never generated. Under an IPython session I did the same thing, but referencing the model as from myapp.models import MyModel
, and worked. Using some debug statements, printing the type
of the model returned by South's orm dict shows the real class, it doesn't appear to be an fake model constructed on the fly by South.
The slug field creates it's value when the pre_save
method. How to force it to be called during a data migration? I need to ensure the uniqueness of the value so when the index is applied in a later schema migration, the columns doesn't contains duplicate values.
Thanks!
BTW: The slug field class does define the south_field_triple
so South plays nice with it.
EDIT: Please see my answer. But more like an answer, it feels more like a hack. Is there a better/right way to do this?
What is Django? Django is a high-level Python web framework that enables rapid development of secure and maintainable websites. Built by experienced developers, Django takes care of much of the hassle of web development, so you can focus on writing your app without needing to reinvent the wheel.
The wildly popular Django Unchained is the most talked about film of the last month, and aside from the controversy, it's popular because of how badass Django is. However, nobody knew about the real Django–a man named Bass Reeves–whom became a Deputy U.S. Marshal in 1875 at the age of 38.
Python has a set of language and object-oriented approach that helps programmers create clear and logical code. Django is a web development python framework that makes it easy to build powerful web applications. The platform comes with useful built-in features found at the Django Admin Interface.
“The technically correct answer,” Willison told me when I asked him about this, “is that a backend framework like Django works with any frontend framework, because of separation of concerns: if a web framework can respond to HTTP requests with JSON and HTML, it can be used with anything.”
Generally you should explicitly replicate the code that generates the field's contents as closely as possible in the migration (A rare example of purposeful code duplication). The code in your approach, even if it worked, would call pre_save as defined at the time of executing the migration, which may have changed or even fail with the models state at the time the migration was created (It may depend on other fields not being present at an earlier time etc.).
So the correct approach in you example would be to use slugify() directly, as it is done in the SlugField's pre_save method:
from django.template.defaultfilters import slugify
class Migration(DataMigration):
def forwards(self, orm):
"Write your forwards methods here."
for myobj in orm['myapp.MyModel'].objects.all():
myobj.slug = slugify(myobj.otherfield)
myobj.save()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With