how to insert list of data into django database? - django

I made a list of items in string that i wanted to insert them into my Country table from shell, well wasn't successful so need some help.(i tried to add it as list and tuple but didn't work just caused more errors)
I use sqlite3 database
models.py
class Country(models.Model):
#countries list
country_name = models.CharField(max_length=100)
a list like this
'Afghanistan', 'Albania', 'Algeria', 'Andorra'

This should do it:
for s in your_list: Country.objects.create(country_name= s)

Related

Django Arrayfiled: Annotate queryset with the first item in the arryafield

I have a model that can be represented by something like this.
class BackPack(models.Model):
person = models.ForeignKey(Person, db_index=True,
related_name='back_packs', on_delete=models.CASCADE)
candy = ArrayField(models.CharField(max_length=203, null=True))
I want to build a queryset that is all back packs associated with one person and then annotated with the first item in the candy arrayfield. I tried the following;
first_candy = BackPack.objects.filter(person__id=200)\
.annotate(first_candy=F('candy__0'))
first_candy = BackPack.objects.filter(person__id=200)\
.annotate(first_candy=ExpressionWrapper(F('candy__0'),
output_field=CharField()))
The output for first_candy includes every item in the arrayfield not just the first one.
Any help for the correct way of doing this is much appreciated.
Try this:
from django.db.models.expressions import RawSQL
BackPack.objects.filter(person__id=200).annotate(first_candy=RawSQL('candy[1]', ()))
Postgres arrays are 1-based by default

how to select fields in related tables quickly in django models

I'm trying to get all values in current table, and also get some fields in related tables.
class school(models.Model):
school_name = models.CharField(max_length=256)
school_type = models.CharField(max_length=128)
school_address = models.CharField(max_length=256)
class hometown(models.Model):
hometown_name = models.CharField(max_length=32)
class person(models.Model):
person_name = models.CharField(max_length=128)
person_id = models.CharField(max_length=128)
person_school = models.ForeignKey(school, on_delete=models.CASCADE)
person_ht = models.ForeignKey(hometown, on_delete=models.CASCADE)
how to quick select all info i needed into a dict for rendering.
there will be many records in person, i got school_id input, and want to get all person in this school, and also want these person's hometown_name shown.
i tried like this, can get the info i wanted. And any other quick way to do it?
m=person.objects.filter(person_school_id=1)
.values('id', 'person_name', 'person_id',
school_name=F('person_school__school_name'),
school_address=F('person_school__school_address'),
hometown_name=F('person_ht__hometown_name'))
person_name, person_id, school_name, school_address, hometown_name
if the person have many fields, it will be a hard work for list all values.
what i mean, is there any queryset can join related tables' fields together, which no need to list fields in values.
Maybe like this:
m=person.objects.filter(person_school_id=1).XXXX.values()
it can show all values in school, and all values in hometown together with person's values in m, and i can
for x in m:
print(x.school_name, x.hometown_name, x.person_name)
You add a prefetch_related query on top of your queryset.
prefetch_data = Prefetch('person_set, hometown_set, school_set', queryset=m)
Where prefetch_data will prepare your DB to fetch related tables and m is your original filtered query (so add this below your Person.objects.filter(... )
Then you do the actual query to the DB:
query = query.prefetch_related(prefetch_data)
Where query will be the actual resulting query with a list of Person objects (so add that line below the prefetch_data one).
Example:
m=person.objects.filter(person_school_id=1)
.values('id', 'person_name', 'person_id',
school_name=F('person_school__school_name'),
school_address=F('person_school__school_address'),
hometown_name=F('person_ht__hometown_name'))
prefetch_data = Prefetch('person_set, hometown_set, school_set', queryset=m)
query = query.prefetch_related(prefetch_data)
In that example I've broken down the queries into more manageable pieces, but you can do the whole thing in one big line too (less manageable to read though):
m=person.objects.filter(person_school_id=1)
.values('id', 'person_name', 'person_id',
school_name=F('person_school__school_name'),
school_address=F('person_school__school_address'),
hometown_name=F('person_ht__hometown_name')).prefetch_related('person, hometown, school')

Using Tag model to create ManytoMany relationship

I am trying to fetch data where the column value "tag" belongs to list from the table "UserBookmark".
UserBookmark.objects.filter(tag__in = ['Java','Android'])
but this returns QuerySet[](null set) whereas I do have data matching this query in table
<QuerySet [<UserBookmark: 21 user12 http://careers.bankofamerica.com/ [u'Java']>,<UserBookmark: 22 user12 http://aehlke.github.io/tag-it/examples.html [u'Data Science,Python']>,<UserBookmark: 23 user13 https://github.com/Azure/azure-quickstart-templates [u'Android']>, <UserBookmark: 24 user14 https://github.com/sunnykrGupta/Bigquery-series [u'Python']>, <UserBookmark: 25 user14 https://github.com/ctfs/write-ups-2017 [u'Data Analytics']>]>
models.py
class UserBookmark(models.Model):
user = models.ForeignKey(User)
bookmark = models.URLField()
tag = models.CharField(max_length = 100)
def __str__(self):
return '%i %s %s %s'%(self.id,self.user,self.bookmark,self.tag)
i have modified my models.py
class UserBookmark(models.Model):
user = models.ForeignKey(User)
bookmark = models.URLField()
tags = models.ManyToManyField('Tag',blank=True)
def __str__(self):
return '%i %s %s'%(self.id,self.user,self.bookmark)
class Tag(models.Model):
name = models.CharField(max_length=100, unique=True)
But when i run python manae.py migrate after python managepy makemigrations, I get this error:
ValueError: Cannot alter field bookmark.UserBookmark.tags into bookmark.UserBookmark.tags - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields)
What am i doing wrong here?
The problem is not in your query, but in the way you are storing your data. You have a single CharField, and you seem to be populating it by simply converting a list to a string. So your records contain for example the literal string "[u'Data Science,Python']".
If you want to store this kind of tag, you need to store the tags separately. One way to do this would be to set up a separate Tag model and use a many-to-many relationship. There are various third-party packages that do this for you - one example is django-taggit.
Try to pluralize, maybe using tags__in

I do not understand this error involving two objects with a many-to-many relation with one another

I am implementing a web interface for email lists. When a list administrator logs in, the site will visually display which lists they are an owner of and corresponding information about the lists. For this I have decided to have two tables:
1) An owner table which contains entries for information about list administrators. Each of these entries contains a 'ManyToManyField' which holds the information about which lists the owner in any given entry is an administrator for.
2) A list table which contains entries with information about each email list. Each entry contains the name of the list a 'ManyToManyField' holding information about which owners are administrators the list.
Here is the code in models.py:
from django.db import models
class ListEntry(models.Model):
name = models.CharField(max_length=64)
owners = models.ManyToManyField('OwnerEntry')
date = models.DateTimeField('date created')
class Meta:
ordering = ('name',)
class OwnerEntry(models.Model):
name = models.CharField(max_length=32)
lists = models.ManyToManyField('ListEntry')
class Meta:
ordering = ('name',)
I have already set up a simple local database to create a basic working website with. I have populated it with test entries using this code:
from list_app.models import *
from datetime import *
le1 = ListEntry(
name = "Physics 211 email list",
date = datetime.now(),
)
le1.save()
le2 = ListEntry(
name = "Physics 265 email list",
date = datetime(2014,1,1),
)
le2.save()
oe1 = OwnerEntry(
name = 'wasingej',
)
oe1.save()
oe1.lists.add(le1,le2)
le1.owners.add(oe1)
le2.owners.add(oe1)
oe2 = OwnerEntry(
name = 'doej',
)
oe2.save()
oe2.lists.add(le1)
le1.owners.add(oe2)
Here is where my error occurs: When the user has logged in via CAS, I have them redirected to this page in views.py:
def login_success(request):
u = OwnerEntry(name=request.user)
print(u.name)
print(u.lists)
return HttpResponse("login success!")
At the line 'print(u.lists)', I get the error "" needs to have a value for field "ownerentry" before this many-to-many relationship can be used.
What am I doing wrong here?
Your model structure is broken, for a start. You don't need ManyToManyFields on both sides of the relationship, only one - Django will provide the accessor for the reverse relationship.
Your issue is happening because you are not querying an existing instance from the database, you are instantiating an unsaved one. To query, you use model.objects.get():
u = OwnerEntry.objects.get(name=request.user.username)
You need to provide the actual class to the ManyToManyField constructor, not a string.
https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/

Many-to-many "by proxy" relathionship in django

My data model consists of three main entities:
class User(models.Model):
...
class Source(models.Model):
user = models.ForeignKey(User, related_name='iuser')
country = models.ForeignKey(Country, on_delete=models.DO_NOTHING)
description = models.CharField(max_length=100)
class Destination(models.Model):
user = models.ForeignKey(User, related_name='wuser')
country = models.ForeignKey(Country)
I am trying to create a queryset which is join all sources with destinations by user (many to many). In such a way I would have a table with all possible source/destination combinations for every user.
In SQL I would simple JOIN the three tables and select the appropriate information from each table.
My question is how to perform the query? How to access the query data?
In django queries are done on the model object, its well documented. The queries or querysets are lazy and when they execute they generally return a list of dict, each dict in the list contains the field followed by the value eg: [{'user':'albert','country':'US and A :) ','description':'my description'},....].
All possible source,destination combinations for every user?
I think you will have to use a reverse relation ship to get this done eg:
my_joined_query = User.objects.values('user','source__country','source__description','destination__country')
notice that i'm using the smaller case name of the models Source and Destination which have ForeignKey relationship with User this will join all the three tabels go through the documentation its rich.
Edit:
To make an inner join you will have to tell the query, this can be simply achieved by using __isnull=False on the reverse model name:
my_innerjoined_query = User.objects.filter(source__isnull=False,destination__isnull=False)
This should do a inner join on all the tables.
Then you can select what you want to display by using values as earlier.
hope that helps. :)