South migrate error: name 'UUID' is not defined - django

I have a model with a CharField field with a default value of uuid4:
f = models.CharField(default=uuid4, max_length=36, unique=True, blank=True)
and this is causing the following error:
Cannot successfully create field 'f' for model
'm': name 'UUID' is not defined.
running the migrate commmand! Ho can I fix this issue? so far I tried:
to define a "wrapper function" in the module for uuid (ie: def getUUID())
to set the default value of "f" by overriding the Model constructor
...but the problem remains :(
ps. I know that I can instruct south for custom fields, but I'm not using custom fields in my opinion :P

I solved defining the following helper function in my model's module:
from uuid import uuid4
def generateUUID():
return str(uuid4())
then:
f = models.CharField(default=generateUUID, max_length=36, unique=True, editable=False)
south will generate a migration file (migrations.0001_initial) with a generated UUID like:
default='5c88ff72-def3-4842-8d48-a75bb3240bb5'
this is pretty unhappy... since that string is "static", instead it must be created dynamically using the helper function... anyway in the django's world al seems working as expected... I added some records into the database and a new UUID was generated for each one. I then tried my first schema migration by adding a couple of fields to my model and they has been added to the database table as expected.

You can also import UUID in your migration:
from uuid import UUID

I simply removed a uuid directory from 'node_modules' directory.
And then I reinstall uuid and it worked.
I hope it helped you guys <3

step 1 : install uuid
npm install uuid
step 2: then import it
import { v4 as uuid } from 'uuid';
step 3: Use it
id:uuid()

Related

Django CharField unique=True seems not working while unique=True is set

I'm using Django 3.0.2 and sqlite3 DB.
I set following simple models:
from django.db import models
class Description(models.Model):
IDENTIFIER_LENGTH = 30
identifier = models.CharField(max_length=IDENTIFIER_LENGTH, blank=False, unique=True, primary_key=True)
Strangely, the unique=True seems not working. Following code run in shell mode
from testunique.models import Description
object = Description('first-object')
object.save()
object.save()
doesn't raise any error. For the record, here is the SQL code of the migrations:
BEGIN;
--
-- Create model Description
--
CREATE TABLE "testunique_description" ("identifier" varchar(30) NOT NULL PRIMARY KEY);
COMMIT;
What is wrong here? Thanks for the answer.
Django considers records with a set primary key as records already in the database. Therefore it will not perform a INSERT … query, but an UPDATE …. It is sometimes used as a trick to set the primary key in Django to None to make a copy of a given record (since then Django will make another INSERT … query).
You can force insertion with:
Description.objects.create(name='first-object')
Description.objects.create(name='first-object') # raises an error
or you can work with force_insert=True:
Description(name='first-object').save(force_insert=True)
Description(name='first-object').save(force_insert=True) # raises an error

Indexing Taggit tags with Algolia for Django: '_TaggableManager' object has no attribute 'name'

I'm having some issues using the Algolia Django integration with one of my models which contains a TaggitManager() field. I'm currently being thrown back the following error when running this command:
$ python manage.py algolia_reindex
AttributeError: '_TaggableManager' object has no attribute 'name'
I've had a look at the Taggit documentation, but I'm just not sure exactly how I would marry the method outlined with the Algolia search index method.
index.py:
import django
django.setup()
from algoliasearch_django import AlgoliaIndex
class BlogPostIndex(AlgoliaIndex):
fields = ('title')
settings = {'searchableAttributes': ['title']}
index_name = 'blog_post_index'
models.py:
from taggit.managers import TaggableManager
class Post(models.Model):
...some model fields...
tags = TaggableManager()
To index the taggit tags with your Post fields, you will need to expose a callable that returns a Blog Post's tags as a list of strings.
The best option is to store them as _tags, which will let you filter on tags at query time.
Your PostIndex would look like this:
class PostIndex(AlgoliaIndex):
fields = ('title', '_tags')
settings = {'searchableAttributes': ['title']}
index_name = 'Blog Posts Index'
should_index = 'is_published'
As for Post:
class Post(models.Model):
# ...some model fields...
tags = TaggableManager()
def _tags(self):
return [t.name for t in self.tags.all()]
Following these instructions, your records will be indexed with their respective tags:
You can check the taggit branch of our Django demo, which demonstrates these steps.
To answer my own question. I have now passed in both the model and the model index so Algolia now knows what to index and what not to index. Although I would like a method to allow Algolia to index taggit tags, alas, it is probably not possible.
My apps.py file:
import algoliasearch_django as algoliasearch
from django.apps import AppConfig
from .index import PostIndex
class BlogConfig(AppConfig):
name = 'blog'
def ready(self):
Post = self.get_model('Post')
algoliasearch.register(Post, PostIndex)
My index.py file:
from algoliasearch_django import AlgoliaIndex
class PostIndex(AlgoliaIndex):
fields = ('title')
settings = {'searchableAttributes': ['title']}
index_name = 'Blog Posts Index'
should_index = 'is_published'
And that should pretty much work! Simple when you know how, or after trying about 10 different options!
So since nobody is answering I tell you how I solved this issue but I have to say that it is not a nice Way and not a "clean" Solution at all. So what I did is went into "taggit managers" in the site-packages (env->lib->python2.x/3.x-> site_packages->taggit->managers.py) In the managers.py file you will find at line 394 this beautiful piece of code:
def __get__(self, instance, model):
if instance is not None and instance.pk is None:
raise ValueError("%s objects need to have a primary key value "
"before you can access their tags." % model.__name__)
manager = self.manager(
through=self.through,
model=model,
instance=instance,
prefetch_cache_name=self.name, # this is the line I comment out when building the index,
name=self.name #this is the line I added and needs to be commented out after the index is build.
)
return manager
So what I do when I want to rebuild the search index is comment out (putting"#" infront of the line) prefetch_cache_name=self.name, and replace it with name=self.name. So building the index will work. After the Index is finished building, you have to bring everything back as it was before (switch the "#" to name=self.name again and leave prefetch_cache_name=self.name, visible again).
As already mentioned this is probably not the best way but I had the same pain and this is working for me. It takes one minute when you have the routine. Since I have to rebuild the Index maybe once every two weeks, that isn't such a deal for me but if you have to do it very often this might be annoying...
Anyway I hope that helps you.
It can help you if you using django==2+
The problem is in get_queryset() method of TaggableManager
Open file with it (my path was: Pipenv(project_name)/lib/site-packages/taggit/manager.py)
Find _TaggableManager class and change method name get_queryset to get_query_set
Done. I wish taggit's developers will fixed this in future updates

Django migration default value callable generates identical entry

I am adding a new field to an existing db table. it is to be auto-generated with strings.
Here is my code:
from django.utils.crypto import get_random_string
...
Model:
verification_token = models.CharField(max_length=60, null=False, blank=False, default=get_random_string)
I generate my migration file with ./manage.py makemigrations and a file is generated.
I verify the new file has default set to field=models.CharField(default=django.utils.crypto.get_random_string, max_length=60)
so all seems fine.
Proceed with ./manage.py migrate it goes with no error from terminal.
However when i check my table i see all the token fields are filled with identical values.
Is this something i am doing wrong?
How can i fix this within migrations?
When a new column is added to a table, and the column is NOT NULL, each entry in the column must be filled with a valid value during the creation of the column. Django does this by adding a DEFAULT clause to the column definition. Since this is a single default value for the whole column, your function will only be called once.
You can populate the column with unique values using a data migration. The procedure for a slightly different use-case is described in the documentation, but the basics of the data migrations are as follows:
from django.db import migrations, models
from django.utils.crypto import get_random_string
def generate_verification_token(apps, schema_editor):
MyModel = apps.get_model('myapp', 'MyModel')
for row in MyModel.objects.all():
row.verification_token = get_random_string()
row.save()
class Migration(migrations.Migration):
dependencies = [
('myapp', '0004_add_verification_token_field'),
]
operations = [
# omit reverse_code=... if you don't want the migration to be reversible.
migrations.RunPython(generate_verification_token, reverse_code=migrations.RunPython.noop),
]
Just add this in a new migration file, change the apps.get_model() call and change the dependencies to point to the previous migration in the app.
It maybe the token string to sort, so django will save some duplicates values. But, i'm not sure it is your main problem.
Anyway, I suggest you to handle duplicates values using while, then filter your model by generated token, makesure that token isn't used yet. I'll give you exampe such as below..
from django.utils.crypto import get_random_string
def generate_token():
token = get_random_string()
number = 2
while YourModel.objects.filter(verification_token=token).exists():
token = '%s-%d' % (token, number)
number += 1
return token
in your field of verification_token;
verification_token = models.CharField(max_length=60, unique=True, default=generate_token)
I also suggest you to using unique=True to handle duplicated values.

Slugfield in tango with django

I'm reading this tutorial to lear the basics of django and I'm facing a problem I can't solve.
I'm at this page http://www.tangowithdjango.com/book17/chapters/models_templates.html at the sluglify function approach.
In the tutorial the author says we have to create a new line in our category model for th slugfield. I folow strictly all the steps just as I show here:
from django.db import models
from django.template.defaultfilters import slugify
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
likes = models.IntegerField(default=0)
views = models.IntegerField(default=0)
slug = models.SlugField(unique=True)
def __unicode__(self):
return self.name
class Page(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length=128)
url = models.URLField()
views = models.IntegerField(default=0)
def __unicode__(self):
return self.title
When I run the "makemgiration" command everything works as expected: I choose the first option and provide ‘’ . BUT when I run "migrate" I get:
django.db.utils.Integrity error: Slug column is not unique
What is going on here? I've repeated several times the migrations and tried other default codes but with the same ending. I can't figure out what im doing wrong. They only thing left is that i'm giving something else instead of ‘’ (Firstly I thoughtthey were '' or ").
Thankyou for your time and help!
Delete db.sqlite3 and re run
python manage.py syncdb
Then perform the migrations
python manage.py makemigrations rango
python manage.py migrate
and re run your population script. This is a downside of Django that whenever you change models.py the db must be recreated.
I am also going through the tutorial and I was having the same issue a couple days ago.
I believe the problem is that you are trying to add a new field (slug) and have it be unique for each of the elements in your table but if I'm not mistaken you already have some data in your table for which that value does not exist and therefore the value that this field would get for those rows is not unique, hence the "django.db.utils.Integrity error: Slug column is not unique".
What I did was simply to delete the data in the table (because it was only a couple of fields, so no big deal) and THEN perform the addition of the field to the model. After doing that, you can put the data back in the table (if you're following the tutorial you should have a script for automated table population so you just run that script and you're golden). Once you have done that, all the rows in the table should have a unique slug field (since it is automatically generated based on the category name) and that solves the problem.
Note that if your table is very large, this may not be a very good solution because of the deletion of data so perhaps there is a better way, like adding that field to the model without it being unique, then running a script that sets the slug field for every row to an unique value and then setting the model's field as unique but I'm not very knowledgeable on SQL and the first solution worked just fine for me so it should work for you as well.
try deleting the sqlite3.db file from the project's directory. i was stuck on a similar problem and that really works..also even if you modify your population script, you have to delete and the recreate the db file to see the changes made....

using uuid as id/pk in django breaks admin page

i am using django 1.0.4 and have 3 models: Category <-1-m-> Item <-1-m-> Image.
i recently changed the id/pk to uuid:
id = models.CharField(max_length=32, primary_key=True,
default=make_uuid, editable=False)
...
def make_uuid():
return str(uuid.uuid4()).replace('-','')
after i started using uuid, the Item's admin page would no longer let me inline add an Image. it would give me a form validation error even though there isn't any error. furthemore, if an Item has an Image, i can't change the Category, it would give me the following error:
KeyError at /admin/inventory/item/90965921681b4b69880b36bd716b0831/
id
...
/local/env/bfi2/lib/python2.6/site-packages/Django-1.0.4-py2.6.egg/django/forms/forms.py in _raw_value
213. field = self.fields[fieldname]
i think this is similar to the following bug: http://code.djangoproject.com/ticket/10992. ideally, i would like to avoid upgrading django and just patch the necessary files. has anyone else ran into this problem?
thanks,
steve
I've gone into such problems but they got solved with django-extensions UUID field.
But I cannot guarantee that this Field will work with an old django version, it was on 1.2.3