일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 장고로 ERP
- 중량 관리
- pip 오류
- 장고
- pyside6
- orm 최적화
- QApplication
- qpa_plugin
- django drf
- django test
- django
- pip 설치
- Self ERP
- channels
- ERP
- materialized
- qwindows.dll
- Python
- tensorflow
- 재고 관리
- test drive development
- django role based
- django erp
- pyside6 ui
- 파이썬
- optimization page
- django rank
- query 최적화
- uiload
- 페이지 최적화
- Today
- Total
취미삼아 배우는 프로그래밍
self erp system 만들기 로그.191102 본문
0. 지금까지의 결과물!
-
폼을 통해 데이터를 입력
-
Django-Rest-Framework를 통해 json으로 결과 값 확인
-
클라이언트(html쪽)단에서 json을 표로 출력
1. 삽질 스토리
0) 폼 입력의 구현과정
- 내장된 폼 팩토리를 이용한다.!
동영상 강좌를 참고했다.
https://www.youtube.com/watch?v=6oOHlcHkX2U&t=221s
https://www.youtube.com/watch?v=3XOS_UpJirU&t=855s
ㅁ 테스트해본 것(이라 쓰지만 삽질)
기능 |
느낌 |
forms.modelformset |
간단한 폼을 출력하는거 있어서, 딱 한 줄로 폼셋을 만들어버린다. 예시) test_modelFormset = forms.modelformset_factory(test_model,exclude=(),extra=1) 단점은 그만큼 추가기능 사용에 제한이 생긴다는 것인데, 어느정도는 옵션등을 사용할 수 있는듯 하다. * 옵션이 많아지면 가독성이 무지하게 떨어지는 느낌.. |
FormFactory |
마찬가지로 간단히 작성을 해주기는 하지만, 세부적인 조정에 있어선 매우 힘이들었다. |
Class Form(사용) |
어쩔 수 없이 사용하는 거긴 하지만, 기능이 너무 많아서.. 사용하기 힘들었다. 대게의 예제들이 이것을 사용하고 있었다. |
** 상기 사실은 모두 주관적인 느낌. |
ㅁ Form -> View -> Template
사실 폼을 작성함에 있어서, 그냥 넘겨주기만 하면 알아서 잘 뜬다.
test_modelFormset = forms.modelformset_factory(test_model,exclude=(),extra=1)
form_third = test_modelFormset(request.POST or None)
이 form_third 를 Template에 던져주고
<div>
<form method='POST' autocomplete="off" > {% csrf_token %}
{{ form_third }}
<button class="waves-effect waves-light btn"><i class="material-icons left">cloud</i>저장</button>
</form>
</div>
그냥 템플릿에 이렇게만 써도
다 나오긴 다 나온다.
문제는 커스터마이징이 힘들다는것에 있었다
나는 Materialize CSS를 사용하고 있는 중인데,
요게 요물이다.
bootstrap에 맞춰져 있는 django에서
materialized 를 애초부터 사용하는거 자체가 큰 욕심이었나보다.
간단하게 될 줄 알았지만, 간단한걸 복잡하게되는 사태가 생겼다.
Materialized 때문에 편리한 폼셋을 버리고 폼을 받아다가 재가공하는 작업을 해야 했다..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<div class="container">
<form method='POST' autocomplete="off" class="col s12" > {% csrf_token %}
<div class="row">
{% for field in form.visible_fields %}
<div class="input-field inline">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
<div class="divider"></div>
<div>
{% for field in form_detailed.visible_fields %}
<div class="input-field col s6">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
</div>
<div class="col s6">
<table>
<thead>
</thead>
</table>
</div>
<div>
<button class="waves-effect waves-light btn"><i class="material-icons left">cloud</i>저장</button>
</div>
</form>
</div>
</div>
|
cs |
대충 이런 느낌으로 재가공했다.
언뜻 보기에 간단해보이지만,,
시행착오가 많고 무진장 어려웠다.
나타난 폼에서의 문제점은
체크박스
날짜(DatePicker)
일단 체크박스를 현 상태에서 해결할 방법이 떠오르지 않아서,
그냥 다 빼버렸다.
그리고, DatePicker는 도저히 빼낼생각이 떠오르지 않다가, 해결하게 됐는데,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
base_date_format = '%Y/%m/%d'
class DetailedInformation(forms.ModelForm):
#non_standard_coat_complete_chk = forms.BooleanField()
#non_standard_coat_complete_chk = forms.BooleanField()
final_date = forms.DateField(widget = forms.DateInput(format=base_date_format),
input_formats=(base_date_format,),
required=False, label='납기일')
submit_date = forms.DateField(widget = forms.DateInput(attrs={'class': "input-lg"},format=base_date_format,),
input_formats=(base_date_format,),
required=False, label='접수일')
#non_standard_coat_complete_chk = forms.BooleanField(widget = forms.CheckboxInput(attrs={'checked':'checked'}))
class Meta:
model = wall_info
exclude = ('wall_name','non_standard_coat_complete_chk','addings_manufacturing',
'non_standard_manufacturing_chk','non_standard_outing_chk','standard_complete_chk','notes',
'final_date','standard_count',)
def __init__(self, *args, **kwargs):
#이거 작동하긴하는거야?
super(DetailedInformation, self).__init__(*args, **kwargs)
self.fields['final_date'].localize = True
self.fields['final_date'].widget.is_localized = True
|
cs |
대충 이런식으로 작성했다.
Meta 쪽에서 체크박스와 기타 불필요한 것들 및 날짜 선택 관련 부분을 모두 뺏다.
윗쪽의 base_date_format은 date에 관하여 폼을 입력받는 형식을 지정하는 것이다.
이 양식과 다르면 똑바로 적으라고 오류가 생기는 그런 식으로 된다.
뷰 단과 맞춰줘야한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
var set_months=['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'];
var set_weekdayShort = [ '일', '월', '화', '수', '목', '금', '토'];
$(document).ready(function(){
$('#id_final_date').datepicker({
format:"yyyy/mm/dd",
autoClose:true,
i18n:{
months:set_months,
weekdaysShort:set_weekdayShort,
monthsShort:set_months,
},
});
var elem = $('#id_submit_date');
$('#id_submit_date').datepicker({
format:"yyyy/mm/dd",
autoClose:true,
defaultDate:new Date(),
setDefaultDate:true,
i18n:{
months:set_months,
weekdaysShort:set_weekdayShort,
monthsShort:set_months,
},
});
});
|
cs |
HTML쪽에서 DatePicker를 사용하도록 설정해준다.
이때 폼셋의 element 아이디는 id_필드명
이 돼고 이걸로 Materialize DatePicker를 사용해주면 된다.
여기 yyyy/mm/dd 는 입력하는 양식 이다.
- 그치만 또 문제가 생겼다.
폼셋이야 그냥 저렇게 어찌어찌 만든다 쳐도.
Foreing Key를 통한 데이터 저장은 해본 적이 없다.
검색해보면 데이터 모델에 대한 설명과
shell로 이렇게 써라.. 만 있을 뿐
somefield.objects.filter(pk=5)
막 이런식으로밖에 없었다.
어려웠다.
그치만, 그냥 내 마음대로 해냈다.
문제는 다음에 생각하자..
일단 지금 작성하고자 하는건 방법론 그 자체이기 때문에,
꼼수는 없이, 일단은 코드부터
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
def drawings_submit_view(request):
form = Drawings_input(request.POST or None)
form_is_success = 'false'
form_detailed = DetailedInformation(request.POST or None)
form_third = test_modelFormset()
if(request.method=='POST'):
if(all([form.is_valid(),form_detailed.is_valid()])):
obj,created = test_model.objects.get_or_create(**form.cleaned_data)
obj_pk = obj.id
#get_instance = wall_info.objects.get(wall_name__id=obj.id)
obj_info, created = wall_info.objects.get_or_create(wall_name__id=obj.id)
if(created):
obj_info.wall_name_id = obj_pk
else:
obj_info.__dict__.update(**form_detailed.cleaned_data)
obj_info.save()
form_is_success='true'
form = Drawings_input()
form_detailed = DetailedInformation()
else:
form_is_success = 'not'
context = {
'form':form,
'form_detailed':form_detailed,
'form_is_success':form_is_success,
'form_third':form_third,
}
return render(request, "modeltest/modeltest_index.html",context)
|
cs |
form_is_success 부분은 미래의 내가 없앨 부분이라 무시하면 된다.(그치?)
시행착오들의 흔적들이 남아있는 그런 코드라, 지금은 좀 너저분하다.
그치만 볼 흐름은 딱 두 개다.
form, form_detailed
obj,created = test_model.objects.get_or_create(**form.cleaned_data)
obj_info, created = wall_info.objects.get_or_create(wall_name__id=obj.id)
if(created):
obj_info.wall_name_id = obj_pk
else:
obj_info.__dict__.update(**form_detailed.cleaned_data)
메인 코드는 이거다.
get_or_create 를 통해
해당 데이터들이 있다면, obj 에는 그 결과값(get이니 무조건 한 개)에 대한
인스턴스를 잡고 created에는 false를 넣는다.
그게 아니라면 obj에는 만들어서 그 인스턴스를 잡고 created에는 True를 넣는다.
그리고 어쨋든 잡게된 obj 인스턴스에서의 id값을 pk 값으로 wall_name(Foreing Key 사용 모델)에 입력시킨다.
그럼 cool 끝난다.
Model A에 대한 id 값은 결국 Unique 하게 사용 때문에, 뻘짓만 안 한다면(해봤기때문에 암),
get을 통해 이상한 데이터 값이 잡히는 오류는 생기지 않는다.
정상적으로 돌아갈 수 밖에 없는 이유는 이 때문,,
검색 하다 보니, get or created에서 Transaction이 생긴다고 하는데
걍 무시하려 한다. 내 예상으로 우리쪽 사용자들은 그렇게 동시다발적으로 데이터를 입력하진 않는다... 아마도.?
그럼 이제 업데이트 부분이 남았는데,
업데이트는
if(created):
obj_info.wall_name_id = obj_pk
else:
obj_info.__dict__.update(**form_detailed.cleaned_data)
결국 마지막에 있는 created의 값이 foreign key 가 들어 간 인스턴스를 잡았는지 새로 만들었는지에 대한 여부기 때문에,
이걸로 판단하여, 업데이트를 시킨다.(처음에는 삭제하고 다시만들게 했었다.)
1) Django-Rest-Framework를 통해 json으로 결과 값 확인
- 처음엔 생각했다.
일단 Django로 모든걸 할 수 있고나서 부터 저걸 건드리자 !
list 에는 순서가 있는법 !
: 그래서 정말 큰 삽질이 시작됐다.
: Django로는 간단한 표 밖에 만들지 못한다.
아니, 만들 수는 있지만, 만약 스케일이 커질 경우 사용자의 요청에 대해 모든 작업을 서버에서 부담하고
그 부담은 다시 사용자에게 가는 셈이 된다.
서버는 데이터만 전달하고, 보는쪽에서 그 데이터를 처리하는게 맞지 않을까?
- 그러고보니 결국 분산돼야 하는셈이다.
사용자도 어느정도의 부담을 동반한다는 것인데, 딱히 문제는 없는것 같다.
양이 많으면 렉이야 원래 걸리는것 아닌가.
그치만, 분산되야 한다는 건 나도 여러모로 html을 건드렸다가, python 을 건드렸다가.
다각화 적인 고통을 동반한다는 뜻이었다.
쨌뜬, 그러했다.
생각보다. Django 를 Serialize 시켜서 json으로 보내는건 간단했다.
django-rest-framework가 이름이 길어서 어려운줄 알았는데,
어려운 일을 쉽게 만들어주는 도구였다. 물론 이것도 복잡하게 하면 어렵긴 하겠지..
#views.py
1
2
3
4
5
6
|
class dataDetaileddataView(viewsets.ModelViewSet):
queryset = wall_info.objects.all()
serializer_class = detail_InfoSerializer
def perform_create(self, serializer):
serializer.save()
|
cs |
# serializers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
from rest_framework import serializers
from .models import test_model, wall_info
class baseInfoSerializer(serializers.ModelSerializer):
class Meta:
model = test_model
fields = ('company_name','location_name','cat_1','cat_2')
class detail_InfoSerializer(serializers.ModelSerializer):
wall_name = baseInfoSerializer(required=True)
class Meta:
model = wall_info
fields = '__all__'
def to_representation(self, instance):
my_fields = {'manufacturing_id', 'non_stnadard_area', 'standard_count', 'second_manufacturing',
'addings_manufacturing', 'final_date', 'non_standard_coat_complete_chk',
'non_standard_manufacturing_chk', 'non_standard_outing_chk', 'standard_complete_chk',
'standard_complete_chk','notes','salesman_name','drawing_designer'}
data = super().to_representation(instance)
for field in my_fields:
try:
if not data[field]:
data[field] = ""
except KeyError:
pass
return data
## 일단 이건 안됨!!
### Foreing Key를 쓰는 바람에 험난해짐.
def create(self, validated_data):
return wall_info.objects.create(**validated_data)
|
cs |
detail_InfoSerializer 내의 to_representaition은
보내줄 json 데이터를 교정해줄 때 사용해주는 함수인듯 하다.
따로 사용하라는 말을 안 했는데, 알아서 사용한다.
저거는 데이터 내에 값이 없을 경우
null 지옥을 보게 되는데, null을 없애게 하려 넣었다.
3. 앞으로.
이제 표 내부에서 체크박스 클릭하는 걸 ajax처리로 하는것 을 넣고
표를 조금 더 다듬고
규격 부분에는
표 안의 표를 집어넣어서 조금 더 크게 하여 표현하려 한다.
삽질이 하도 많아서 되게 글이 길 줄 알았는데
뭐가 된게 없어서 그런지 별 내용이 없는것 같다.
ㅠ
'파이썬(장고)' 카테고리의 다른 글
Django Custom User 일지 (0) | 2019.12.26 |
---|---|
20191222 드디어 한 페이지는 완성되간다. (3) | 2019.12.22 |
django-channels-database-tableout (0) | 2019.10.31 |
python ERP. 모델을 작성해보자.(부제: 삽질일기) (0) | 2019.10.20 |
Python Django . ERP . 모델을 작성해보자. (0) | 2019.10.15 |