I created a form based on a model. The model has a many2many field. I defined the field like this:
contacts = models.ManyToManyField(Contact, blank=True, null=True)
I`m wondering now why the generated form says that this field cannot be blank. I always get the error message "This field is required.", when i do not select a contact for the contacts field.
Whats`s wrong?
In your form declaration mark this field as required=False
class MyForm(forms.ModelForm):
contacts=forms.ModelMultipleChoiceField(queryset=Contact.objects.all(),required=False)
class Meta:
model=MyModel
Possibly you did syncdb before adding blank=True, null=True?
syncdb will only create tables if they don't exist in the database. Changes to models have to be done manually in the database directly with SQL or using a migration tool such as South.
Of course, if you are still in early development, it will be easier to drop the database and run syncdb again.
Your use of null=True is confusing here. A manyToMany field results in a 3rd table relating one model to another. e.g.
Business <-> Contact
If business.contacts is empty, no records are entered into this table. null=True would make me think you are intending for NULL records to be added to this table, which doesn't seem valid.
Typically you would leave both of these attributes off.
Related
I've been looking for a good database design for a twitter like social network site in my django project and I found two possibilities:
This one down here
class Following(models.Model):
follower = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='following')
following = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='followers')
And this other one
class User(AbstractUser):
follows = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='followed_by')
pass
Are these the same? Is there any difference here? Which one should I choose? I'm kind of new to this so I can`t figure out which one is the best option. I find the first one easier to understand.
If I add this to my user model
following = models.ManyToManyField('self', related_name="followers")
and run (assuming auth is the app where your user model is, and replacing 000X by the number of the generated migration)
python manage.py makemigrations auth
python manage.py sqlmigrate auth 000X
this is what I get:
CREATE TABLE `auth_user_following` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`from_user_id` integer NOT NULL, `to_user_id` integer NOT NULL);
ALTER TABLE `auth_user_following` ADD CONSTRAINT `auth_user__from_user_id_b9318b74_fk_auth_`
FOREIGN KEY (`from_user_id`) REFERENCES `auth_user` (`id`);
ALTER TABLE `auth_user_following` ADD CONSTRAINT `auth_user__to_user_id_b51bc961_fk_auth_`
FOREIGN KEY (`to_user_id`) REFERENCES `auth_user` (`id`);
ALTER TABLE `auth_user_following` ADD CONSTRAINT `auth_user_foll_from_user_id_to_au_88cd5a29_uniq`
UNIQUE (`from_user_id`, `to_user_id`);
So it creates a table with an auto-generated id and two foreign key columns, just as it would do with the explicit relation-only model, i.e. on the database side, there is no structural difference.
For code readability, I would much prefer to keep the relation in the model and not define it in a different class. However, if you want to add additional data to the relation (e.g. date_started_following), you will need an explicit relation model. Then, you might still want to mention this many-to-many-relation in your user model and point to the explicit relation using the through argument:
However, sometimes you may need to associate data with the
relationship between two models.
[...]
Django allows you to specify the model that will
be used to govern the many-to-many relationship. You can then put
extra fields on the intermediate model. The intermediate model is
associated with the ManyToManyField using the through argument to
point to the model that will act as an intermediary.
One other reason for the first approach or an explicit through model is that it might facilitate some queries about the relationship, e.g. "find users who follow each other".
I would suggest both models code will work fine.
If you want to create custom user model with new fields then use below code format.
AbstractUser: Use existing fields in the user model
AbstractBaseUser:In case want to create your own user model from
scratch
class User(AbstractUser):
follows = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='followed_by')
pass
You want to segregate your app related changes then use below models code.
class Following(models.Model):
follower = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='following')
following = models.ForeignKey(User, on_delete=models.CASCADE,
related_name='followers')
I currently have a Django powered in-production web app that contains multiple models, sitting on top of a Postgresql database (Google Cloud SQL)
During initial set-up, one of the models was set up as follows:
class ExampleModel(models.Model):
id = models.CharField(max_length=60, unique=True, primary_key=True)
new_id = models.CharField(max_length=60, unique=True, null=True, db_index=True)
name = models.CharField(max_length=300, db_index=True)
tags = models.ManyToManyField(Tag, blank=True)
The id field contains a unique ID like: AB123456789.
I have since realised this is a mistake and would like to revert the primary key field to a standard auto-incrementing autofield, and instead use the 'new_id' field to store the unique ID.
Please can someone provide guidance on how I can make this change and perform the necessary database migrations? There are a number of foreign key fields in other models that currently use the id field in the above model which will need changing. As you can see in the above, there is also a many to many field between this model and a tag model.
I tried removing the id field from my models.py file and migrating - it initially gave an error linked to null fields and default values so I set a dummy default value in the Terminal window and removed this in the migration file.
The database removed the id field successfully and generated a new Autonumber primary key field however none of the many to many or foreign key relationships were kept post migration. I have since rolled back to a prior version of the database.
Generally this will be your approach. Steps 1-4 can be merged into a single deployment. Steps 5-7 into another. Then 8-9 would be the final.
Create new auto field.
Create new FK nullable relationships on models
Update all code that creates related models to populate both FK's
Populate all the null FK fields via a script
Make the new FK fields not-nullable
Make old FK's nullable.
Remove old FK usages from code base
Migration to remove old ID field and FKs.
(optional) Rename auto field to be ID and potentially use Django's built-in field.
I am currently working on a Django project.
I am using Foreign Fields in one of the models.
class Purchase (models.Model):
user = models.ForeignKey(User, blank = True, null = True)
game = models.ForeignKey(Game)
...
And accessing these values in views like
p = Purchase.objects.filter(user=request.user,game=request.POST['gameid'])
In DB(i am using Postgres), the fields in Purchase Table are user_id and game_id
respectively for user and game.
I think its the Django default to suffix foreign fields with _id.
So i tried a bit in manage.py shell
and i came to know that i am getting same amount of results even if i use
p = Purchase.objects.filter(user_id=request.user,game_id=request.POST['gameid'])
So my doubt is that whether the field names defined in model and exact names of those fields in DB can be used interchangeably? Any further information or explanation would be appreciated.
Thanks
Django does this for foreign key fields. If you want to have the same name in the database then you can define column name using db_column:
user = models.ForeignKey(User, db_column='user')
P.S you can use both user_id and user to reference foreign key. This is absolutely fine. But i will suggest you to use model level names to avoid confusions.
I have this model (truncated here for brevity):
class Meal(models.Model):
host = models.ForeignKey(User, related_name="cooking")
cost = models.IntegerField(default=1)
summary = models.CharField(max_length=1024, default="A good dinner")
diners = models.ManyToManyField(User, through='Attendance',
related_name="diners", blank=True)
When I sync it, the diners Field is completely ignored. It doesn't appear in the database and there is no error when running syncdb. It's as if it's not there. The User and Attendance tables are all fine.
I discovered this problem when trying to add this field with South, so I've tried that as an alternative too.
Any ideas?
Thanks
Did you already run syncdb fyrir Meal before you added the diners field?
Because syncdb will not alter existing tables as you can read here:
Django docs
Side note - I have not used south personally but I have used Django evolution while developing.
Edit:
After reading your comment I think I know what the problem is.
When using through with ManyToManyField Django doesn't add a field to that table, all the necessary information is in the attendance table.
i have a problem, my model was without slug field, so now i need to add a slug field, but my models is full of data, im using django evolution and was cool added the new slug field...but how ill update the slug fiel with the data form the title field at once?
Thanks
You want this:
http://south.aeracode.org/
It will allow you to modify your schema but keep your data intact.