Django(8): Model 및 Form 작업
56457 단어 Django
Model 및 Form 및 ModelForm 소개
Admin 로그인 인증, 먼저 ModelForm을 거쳐 Model을 통과합니다.
error_메시지 필드가 있는 모델에서 정오에 바뀌었기 때문에 전단이 효력이 발생하지 않습니다. 왜냐하면 먼저 ModelForm 검증을 거쳤기 때문입니다
1. 모델 조작 보충
1. 데이터베이스 테이블 만들기
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
class Meta: ########## ###########
# app + +
db_table = "tb1" #
index_together = [ #
("name", 'pwd'),
]
# :
# select * from where name='xx' #
# select * from where name='xx' and pwd = 'xx' #
# select * from where pwd = 'xx' #
#
unique_together = (("driver", "restaurant"),)
# admin (verbose_name s)
verbose_name = " " # ==> s
verbose_name_plural=" " # ==>
추가:https://docs.djangoproject.com/en/1.10/ref/models/options/
:models.ForeignKey( )
:models.ManyToManyField( )
:models.OneToOneField( )
한 쌍 한두 개의 제약: 외키 제약;고유한 색인 구속
원투원은 ForeignKey를 계승하기 때문에 ForeignKey의 사용법은 원투원에서 모두 적용된다
def func():
return 5
class UserType(models.Model):
name = models.CharField(max_length=32)
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
fk = models.ForeignKey(to="UserType",to_field='id',on_delete=models.SET(func))
# delete from user where id=1
# delete from UserType where id=1 #
# UserType.objects.filter(id=1).delete()
# Django , , 。
필드 및 매개변수
to, #
to_field=None, #
on_delete=None, # ,
- models.CASCADE, # ,
- models.DO_NOTHING, # , IntegrityError( )
- models.PROTECT, # , ProtectedError(Django )
- models.SET_NULL, # , null( FK )
- models.SET_DEFAULT,# , ( FK )
- models.SET, # ,
a. , :models.SET( )
b. , :models.SET( )
ForeignKey 정방향 및 역방향 작업
#
v = User.objects.all()
for item in v:
item.user
item.pwd
item.fk.name # <====
User.objects.all().values('user','fk__name') # <====
#
v = UserType.objects.all()
for item in v:
item.name
item.id
item.user_set.all() # <== xx_set # <====
models.UserType.objects.all().values('name','user__pwd') # <====
# xx_set, :
fk = models.ForiegnKey(to="UserType",to_field='id',related_name="b")
related_name: 테이블 foreignkey 자신을 사용할 때 누가 자신과 관련이 있는지 확인할 수 있습니다.
related_name=None, # , , 【 _set】 : obj. _set.all()
related_query_name=None,# , , 【 】 : models.UserGroup.objects.filter( __ =1).values(' __ ')
Admin 또는 ModelForm에 연관된 데이터를 표시할 때 사용할 수 있는 기준
limit_choices_to=None, # Admin ModelForm , :
# :
models.ForeignKey(to="UserType",to_field='id',limit_choices_to={'nid__gt': 5})
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}
from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
예:
app에서 admin을 편집합니다.py
from cmdb import models
admin.site.register(models.UserType)
admin.site.register(models.User)
수퍼유저 만들기
python manage.py createsuperuser
Django admin이 로그인하여 개체로 표시되고 다음과 같이 이름이 표시됩니다.
class UserType(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return self.name
limit_choices_to는 관리자 홈페이지의 밑에 있는 값에 대한 선별입니다
db_constraint=True # ,false foreignkey,
parent_link=False # Admin
symmetrical=None, # ,symmetrical
# , symmetrical
models.BB.objects.filter(...)
# :id, code, m1
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=True)
# : bb, id, code, m1
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=False)
a. django
m2m.remove
m2m.add
m2m.set
m2m.clear
m2m.filter()
b. ( m2m )
c. ( m2m )
# m2m " "
# m2m clear
through=None, # ,
through_fields=None, # ,
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
)
class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
inviter = models.ForeignKey(
Person,
on_delete=models.CASCADE,
related_name="membership_invites",
)
invite_reason = models.CharField(max_length=64)
db_constraint=True, #
db_table=None, # ,
2. 데이터베이스 조작 보충의 기본 조작
1. 기본 작업
#
#
# models.Tb1.objects.create(c1='xx', c2='oo') , **kwargs
# obj = models.Tb1(c1='xx', c2='oo')
# obj.save()
#
#
# models.Tb1.objects.get(id=123) # , ( )
# models.Tb1.objects.all() #
# models.Tb1.objects.filter(name='seven') #
#
#
# models.Tb1.objects.filter(name='seven').delete() #
#
# models.Tb1.objects.filter(name='seven').update(gender='0') # , **kwargs
# obj = models.Tb1.objects.get(id=1)
# obj.c1 = '111'
# obj.save() #
2、진급 조작(일어나지 않는 더블 밑줄)
이중 밑줄을 사용하여 필드와 대응하는 조작을 연결하다
#
#
# models.Tb1.objects.filter(name='seven').count()
# ,
#
# models.Tb1.objects.filter(id__gt=1) # id 1
# models.Tb1.objects.filter(id__gte=1) # id 1
# models.Tb1.objects.filter(id__lt=10) # id 10
# models.Tb1.objects.filter(id__lte=10) # id 10
# models.Tb1.objects.filter(id__lt=10, id__gt=1) # id 1 10
# in
#
# models.Tb1.objects.filter(id__in=[11, 22, 33]) # id 11、22、33
# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
# isnull
# Entry.objects.filter(pub_date__isnull=True)
# contains
#
# models.Tb1.objects.filter(name__contains="ven")
# models.Tb1.objects.filter(name__icontains="ven") # icontains
# models.Tb1.objects.exclude(name__icontains="ven")
# range
#
# models.Tb1.objects.filter(id__range=[1, 2]) # bettwen and
#
#
# startswith,istartswith, endswith, iendswith,
# order by
#
# models.Tb1.objects.filter(name='seven').order_by('id') # asc
# models.Tb1.objects.filter(name='seven').order_by('-id') # desc
# group by
#
# from django.db.models import Count, Min, Max, Sum
# models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
# limit 、offset
#
# models.Tb1.objects.all()[10:20]
# regex ,iregex
#
# Entry.objects.get(title__regex=r'^(An?|The) +')
# Entry.objects.get(title__iregex=r'^(an?|the) +')
# date
#
# Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
# Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
# year
#
# Entry.objects.filter(pub_date__year=2005)
# Entry.objects.filter(pub_date__year__gte=2005)
# month
#
# Entry.objects.filter(pub_date__month=12)
# Entry.objects.filter(pub_date__month__gte=6)
# day
#
# Entry.objects.filter(pub_date__day=3)
# Entry.objects.filter(pub_date__day__gte=3)
# week_day
#
# Entry.objects.filter(pub_date__week_day=2)
# Entry.objects.filter(pub_date__week_day__gte=2)
# hour
#
# Event.objects.filter(timestamp__hour=23)
# Event.objects.filter(time__hour=5)
# Event.objects.filter(timestamp__hour__gte=12)
# minute
#
# Event.objects.filter(timestamp__minute=29)
# Event.objects.filter(time__minute=46)
# Event.objects.filter(timestamp__minute__gte=29)
# second
#
# Event.objects.filter(timestamp__second=31)
# Event.objects.filter(time__second=2)
# Event.objects.filter(timestamp__second__gte=31)
3. 고급 조작
아래의 문장처럼 위의 기능은 실현할 수 없다
select id, name, 1,
func(id),
select name from tb2 where nid = id
from tb1;
Entry.objects.filter().extra(select={'cid':"1"}) # sql
select …… , 1 as cid from tb1
Entry.objects.filter().extra(select={'cid':"%s"},select_params=[1])
# %s 1
# extra
#
# extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
# Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
# ==> select * (select name from tb2 where nid = id) as new_id from tb1;
# Entry.objects.extra(select={'new_id':"func()id"}) # mysql
# where ( “,” and,“or” or)
# Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
# Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
# Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
# F
#
# from django.db.models import F
# models.Tb1.objects.update(num=F('num')+1)
# Q
#
# :
# Q(nid__gt=10)
# Q(nid=8) | Q(nid__gt=10)
# Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
# :
# con = Q()
# q1 = Q()
# q1.connector = 'OR'
# q1.children.append(('id', 1))
# q1.children.append(('id', 10))
# q1.children.append(('id', 9))
# q2 = Q()
# q2.connector = 'OR'
# q2.children.append(('c1', 1))
# q2.children.append(('c1', 10))
# q2.children.append(('c1', 9))
# con.add(q1, 'AND')
# con.add(q2, 'AND')
#
# models.Tb1.objects.filter(con)
# SQL
#
# from django.db import connection, connections
# cursor = connection.cursor() # cursor = connections['default'].cursor()
# cursor.execute("""SELECT * from auth_user where id = %s""", [1])
# row = cursor.fetchone()
4. 기타 조작
##################################################################
# PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET #
##################################################################
def all(self)
#
def filter(self, *args, **kwargs)
#
# : , ,Q
def exclude(self, *args, **kwargs)
#
# : , ,Q
def select_related(self, *fields)
: join , 。
model.tb.objects.all().select_related()
model.tb.objects.all().select_related(' ')
model.tb.objects.all().select_related(' __ ')
def prefetch_related(self, *lookups)
: , SQL Python 。
#
# where id in ( ID)
models.UserInfo.objects.prefetch_related(' ')
from django.db.models import Count, Case, When, IntegerField
Article.objects.annotate(
numviews=Count(Case(
When(readership__what_time__lt=treshold, then=1),
output_field=CharField(),
))
)
students = Student.objects.all().annotate(num_excused_absences=models.Sum(
models.Case(
models.When(absence__type='Excused', then=1),
default=0,
output_field=models.IntegerField()
)))
def annotate(self, *args, **kwargs)
# group by
from django.db.models import Count, Avg, Max, Min, Sum
v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id'))
# SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id
v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id')).filter(uid__gt=1)
# SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1
v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id',distinct=True)).filter(uid__gt=1)
# SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1
def distinct(self, *field_names)
# distinct
models.UserInfo.objects.values('nid').distinct()
# select distinct nid from userinfo
: PostgreSQL distinct
def order_by(self, *field_names)
#
models.UserInfo.objects.all().order_by('-id','age')
def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
# , :
Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
def reverse(self):
#
models.UserInfo.objects.all().order_by('-nid').reverse()
# : order_by,reverse ,
def defer(self, *fields):
models.UserInfo.objects.defer('username','id')
models.UserInfo.objects.filter(...).defer('username','id')
#
def only(self, *fields):
#
models.UserInfo.objects.only('username','id')
models.UserInfo.objects.filter(...).only('username','id')
def using(self, alias):
, (setting )
##################################################
# PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
##################################################
def raw(self, raw_query, params=None, translations=None, using=None):
# SQL, queryset
models.UserInfo.objects.raw('select * from userinfo')
# SQL , UserInfo
models.UserInfo.objects.raw('select id as nid from ')
# SQL
models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,])
#
dic = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
tb.objects.raw('select nid,user,email from tb2', dic)
tb.objects.raw('SELECT * FROM some_other_table', translations=dic)
#
models.UserInfo.objects.raw('select * from userinfo', using="default")
################### SQL ###################
from django.db import connection, connections
cursor = connection.cursor() # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
row = cursor.fetchone() # fetchall()/fetchmany(..)
def values(self, *fields):
#
def values_list(self, *fields, **kwargs):
#
def dates(self, field_name, kind, order='ASC'):
#
# kind :"year"( ), "month"( - ), "day"( - - )
# order :"ASC" "DESC"
#
- year : -01-01
- month: - -01
- day : - -
models.DatePlus.objects.dates('ctime','day','DESC')
def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
# 。
# ,
# kind "year", "month", "day", "hour", "minute", "second"
# order :"ASC" "DESC"
# tzinfo
models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC)
models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai'))
""" pytz
pip3 install pytz
import pytz
pytz.all_timezones
pytz.timezone(‘Asia/Shanghai’)
"""
def none(self):
# QuerySet
####################################
# METHODS THAT DO DATABASE QUERIES #
####################################
def aggregate(self, *args, **kwargs):
# ,
from django.db.models import Count, Avg, Max, Min, Sum
result = models.UserInfo.objects.aggregate(k=Count('u_id', distinct=True), n=Count('nid'))
# distinct=True
===> select count(nid) as n from userinfo; {'k': 3, 'n': 4}
def count(self):
#
def get(self, *args, **kwargs):
#
def create(self, **kwargs):
#
def bulk_create(self, objs, batch_size=None):
#
# batch_size
objs = [
models.DDD(name='r11'),
models.DDD(name='r22')
]
models.DDD.objects.bulk_create(objs, 10) # 10 10
def get_or_create(self, defaults=None, **kwargs):
# , , ,
# defaults ,
obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2})
def update_or_create(self, defaults=None, **kwargs):
# , , ,
# defaults
obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1})
def first(self):
#
def last(self):
#
def in_bulk(self, id_list=None):
# ID
id_list = [11,21,31]
models.DDD.objects.in_bulk(id_list)
def delete(self):
#
def update(self, **kwargs):
#
def exists(self):
#
5. 테이블 연결 작업(일어나지 않는 이중 밑줄)
이중 밑줄 및 사용set 테이블 사이의 조작을 연결합니다
테이블 구조 인스턴스
class UserProfile(models.Model):
user_info = models.OneToOneField('UserInfo')
username = models.CharField(max_length=64)
password = models.CharField(max_length=64)
def __unicode__(self):
return self.username
class UserInfo(models.Model):
user_type_choice = (
(0, u' '),
(1, u' '),
)
user_type = models.IntegerField(choices=user_type_choice)
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
address = models.CharField(max_length=128)
def __unicode__(self):
return self.name
class UserGroup(models.Model):
caption = models.CharField(max_length=64)
user_info = models.ManyToManyField('UserInfo')
def __unicode__(self):
return self.caption
class Host(models.Model):
hostname = models.CharField(max_length=64)
ip = models.GenericIPAddressField()
user_group = models.ForeignKey('UserGroup')
def __unicode__(self):
return self.hostname
일대일 작업
user_info_obj = models.UserInfo.objects.filter(id=1).first()
print user_info_obj.user_type
print user_info_obj.get_user_type_display()
print user_info_obj.userprofile.password
user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
print user_info_obj.keys()
print user_info_obj.values()
일대다
1、 __
2、 .
다대다
user_info_obj = models.UserInfo.objects.get(name='u')
user_info_objs = models.UserInfo.objects.all()
group_obj = models.UserGroup.objects.get(caption='CEO')
group_objs = models.UserGroup.objects.all()
#
#group_obj.user_info.add(user_info_obj)
#group_obj.user_info.add(*user_info_objs)
#
#group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)
#
#user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs)
#
#user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs)
#
#print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)
#
#print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CEO')
#print user_info_obj.usergroup_set.all().filter(caption='DBA')
6. 성능 관련
상기 다른 조작에서 언급한
select_related
prefetch_related
은MySQL 최적화, 성능과 관련된 것으로 파악해야 한다.# ( ) ,users , +1 sql
users = models.User.objects.all()
for row in users:
print(row.user,row.pwd,row.ut_id)
print(row.ut.name) # SQL
# , ( : , )
# .values,.values_list, queryset ,
users = models.User.objects.all().values('user','pwd','ut__name')
# select_related ( , , 。)
# , , 。
users = models.User.objects.all().select_related('ut')
for row in users:
print(row.user,row.pwd,row.ut_id)
print(row.ut.name) # SQL
# prefetch_related ( ( + ) 。 。)
# select from users where id > 30 (django , select *, * 。)
# ut_id=[1,2]
# select from user_type where id in [1,2]
# Django , 。
users = models.User.objects.filter(id__gt=30).prefetch_related('ut','tu')
for row in users:
print(row.user,row.pwd,row.ut_id)
print(row.ut.name)
예를 들어 일대일, 일대다, 다대다는 모두 표준적인 데이터베이스 모델이지만 실제 생산에서 이런 모델을 사용하지 않는다. 이런 모델은 하드디스크를 절약하지만 시계 조회 효율조차 느리다.생산 중에는 왕왕 공간으로 시간을 바꾼다.
3. 데이터 검증(full clean 검증)
다음 데이터는 실행 가능하며 검증되지 않았습니다
models.UserInfo.objects.create(name='root',email='root')
obj = models.UserInfo(name='root',email='root')
obj.save
데이터 검증이 수행된 경우
obj.full_clean()
obj.full_clean() # , , try。
obj.save()
clean 갈고리 사용자 정의 검증은 다음과 같습니다
class UserInfo(models.Model):
name = models.CharField(max_length=32)
email = models.EmailField()
def clean(self):
from django.core.exceptions import ValidationError
c = UserInfo.objects.filter(name=self.name).count()
if c:
raise ValidationError(message=" ", code='i1')
그러나 일부 다른 기능은 검증할 수 없고 오타가 바로 전단에 나타나기 때문에 이곳의 검증 기능은 비교적 약하다.
전재는 반드시 이 출처를 보존하십시오:http://blog.csdn.net/fgf00/article/details/54614706
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Django 라우팅 계층 URLconf 작용 및 원리 해석URL 구성(URLconf)은 Django가 지원하는 웹 사이트의 디렉토리와 같습니다.그것의 본질은 URL과 이 URL을 호출할 보기 함수 사이의 맵표입니다. 위의 예제에서는 URL의 값을 캡처하고 위치 매개 변수로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.