Comments (3)
I have solved this issue by updating the pre_save
method like this:
class ExtendedAutoSlugField(AutoSlugField):
def pre_save(self, instance, add):
# get currently entered slug
value = self.value_from_object(instance)
if self.always_update or not value:
value = super(ExtendedAutoSlugField, self).pre_save(instance, add)
return value
If interested, I can make a merge request.
from django-autoslug.
I think the problem here is that the name always_update
is poorly chosen. Instead, it should be called something like always_repopulate
or autorefresh
.
Setting always_update
to True
will apply the slugify function to the populate_from
field on every save. However, and this is very tricky (!), if it's set to False
instead, it will apply the slugify function to the current value of the AutoSlug field.
The current assumption in the code seems to be that slugify(value) == slugify(slugify(value))
, which is correct for slugs. However, the premise of this library is that it can be used for all sorts of fields whose values are computed from values in other fields.
Example:
In models.py
:
from .fields import LongURLField
from .utils import md5_url
class Source(models.Model):
url = LongURLField(null=True, unique=True) # custom url field with max_len > 255
url_md5 = AutoSlugField(populate_from='url', always_update=False, slugify=md5_url, null=True, unique=True)
# more fields here
In utils.py
:
from hashlib import md5
def md5_url(url):
return md5(url.encode("utf-8")).hexdigest()
Application code *
:
source, _ = Source.objects.get_or_create(
url_md5=md5_url(url),
defaults={
'url': url,
# more fields here
}
)
What should happen is that the existing source is taken from the database if the url already exists, and that a new source is created if the url is new.
This didn't work as expected. What happens in the background is this:
source.url_md5 = md5('the-website.com')
source.url = 'the-website.com'
source.save() # wrong md5 value (md5 has now been applied twice)
For a moment, I was considering a silly workaround:
source.url_md5 = md5('the-website.com')
source.url = 'the-website.com'
# (equivalent of adding `'md5_url' : None` to `defaults` in `get_or_create()`)
source.url_md5 = None:
source.save() # correct md5 value
# but
source.save() # wrong md5 value (md5 has now been applied twice)
source.save() # wrong md5 value (md5 has now been applied thrice)
So, although I don't want to update the md5 field once it's set, I do have to set always_update
to True
to fix this issue, which is very counterintuitive.
*
background information: the reason I'm using the md5 for duplication checks and not the url field itself is that longtext
fields don't make good index fields (i.e. lookups will not be as fast)
from django-autoslug.
Summarizing my previous post: there are actually three scenarios, where always_update
as a boolean only gives two:
- Calculate the slugify value only once and lock that value (except for manual changes perhaps)
- Repopulate the slugify value on every save (using the
populate_from
field) - Recalculate the slugify value on every save (reusing the value in the AutoSlug field)
Setting always_update
to True
refers to option 2, whereas setting always_update
to False
refers to option 3. Options 1 and 3 can be considered equivalent if and only if slugify(slugify(value)) = slugify(value)
.
When I started using this library, I expected the choice to be between cases 1 and 2. There may be use cases where option 3 makes sense, e.g. if you want to keep track of the number of saves and the slugify function is a function that adds one to the value.
from django-autoslug.
Related Issues (20)
- AutoSlugField with two charfields HOT 14
- ModuleNotFoundError: No module named 'django.core.urlresolvers' on python 3.6.3 HOT 7
- New release? HOT 12
- Support for Django 2.1.x HOT 11
- unique_with does not work with BooleanFields
- autoslug should work with no arguments
- Include LICENSE and run_tests.py in PyPI sdist
- autoslug 1.9.4 python 3.7.3 django 2.2 import successfull but importlib fails
- How to increase maximum length of AutoSlug field
- Feature request: generating slug from multiple fields HOT 2
- allow_unicode should not be popped off the kwargs HOT 2
- Uniqueness Manager is always overridden
- Doesn't work with Django 3.1 HOT 2
- error when used model.save() HOT 1
- Lambda functions no longer work with Django migrations
- slug that has a dash at the end initially is changed with next model save
- The letter "ษ,รง,ฤฑ" is not supported
- Unique atribute double sense.
- slug doesn't work peoperly in Farsi even with allow_unicode=True
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-autoslug.