CRM项目实战-动态modelform的实现

生成类 f=type("Foo" , (object,) , {'func': })

{% extends 'kingadmin/index.html' %}
{% load kingadmin_tags %}

{% block  right-content-container %}
<h2 class="page-header">{% get_model_name admin_class %}</h2>
<h4 class="page-header">修改{{ form_obj.instance }}</h4>

<div>
change

{% include 'kingadmin/table_obj_change_component.html' %}

</div>

{% endblock %}
{% load kingadmin_tags %}

<form class="form-horizontal"  method="post" onsubmit="VerificationBeforeFormSubmit()"> {% csrf_token %}
 {{ form_obj.errors }}
  {% for field in form_obj %}
  <div class="form-group">
    <label class="col-sm-2 control-label">{{ field.label }}</label>
    <div class="col-sm-10">
      {% if field.name in admin_class.filter_horizontal %}
          <  class="col-lg-5">
                <select id="id_{{ field.name }}_from" multiple class="form-control">
                    {% get_available_m2m_data field.name form_obj admin_class as available_m2m_data %}
                    {% for obj in available_m2m_data %}
                        <option ondblclick=MoveSelectedOption(this,'id_{{ field.name }}_to') value="{{ obj.id }}">{{ obj }}</option>
                    {% endfor %}
                </select>
          </div>
          <div class="col-lg-5">
                <select tag="selected_m2m" id="id_{{ field.name }}_to" multiple class="form-control" name="{{ field.name }}">
                    {%  get_selected_m2m_data field.name form_obj admin_class as selected_m2m_data %}
                    {% for obj in selected_m2m_data %}
                        <option value="{{ obj.id }}" ondblclick=MoveSelectedOption(this,'id_{{ field.name }}_from')>{{ obj }}</option>
                    {% endfor %}

                </select>

          </div>
      {% else %}
        {{ field }}
      {% endif %}
        <span style="color: red">{{ field.errors.0 }} </span>
    </div>
  </div>
  {% endfor %}
  {% if not admin_class.form_add %}   <!--如果这是修改表单-->
      {% for field in admin_class.readonly_fields %}
      <div class="form-group">
        <label class="col-sm-2 control-label">{{ field }}</label>
        <div class="col-sm-10">
          <p>{% get_obj_field_val form_obj field %}</p>
        </div>
      </div>
      {% endfor %}
 {% endif %}
  <div class="form-group">
    <div class="col-sm-offset-11 col-sm-2">
      <button type="submit" class="btn btn-info">Save</button>
    </div>
  </div>
</form>


<script>

    function  MoveSelectedOption(ele,target_id) {

        var new_target_id = $(ele).parent().attr('id');
        var option = "<option value='" + $(ele).val() +"'ondblclick=MoveSelectedOption(this,'"+ new_target_id +"') >" + $(ele).text() +"</option>";
        $("#"+ target_id).append(option);
        $(ele).remove();

    }


    function VerificationBeforeFormSubmit() {


        $("select[tag] option").prop('selected',true);

    }
</script>
table_change_list.html
from django.template import Library
from django.utils.safestring import mark_safe
import datetime ,time
register = Library()

@register.simple_tag
def build_filter_ele(filter_column,admin_class):

    column_obj = admin_class.model._meta.get_field(filter_column)
    print("column obj:",column_obj)
    try:
        #filter_column_name = "<span>%s</span>" % filter_column
        filter_ele = "<div class='col-md-2'>%s<select class='form-control ' name='%s'>" % (filter_column,filter_column)
        for choice in column_obj.get_choices():
            selected = ''
            if filter_column in admin_class.filter_condtions:#当前字段被过滤了
                # print("filter_column", choice,
                #       type(admin_class.filter_condtions.get(filter_column)),
                #       admin_class.filter_condtions.get(filter_column))
                if str(choice[0]) == admin_class.filter_condtions.get(filter_column):#当前值被选中了
                    selected = 'selected'
                    print('selected......')

            option = "<option value='%s' %s>%s</option>" % (choice[0],selected,choice[1])
            filter_ele += option
    except AttributeError as e:
        print("err",e)
        filter_ele = "<div class='col-md-2'><select  class='form-control' name='%s__gte'>" % filter_column
        if column_obj.get_internal_type() in ('DateField','DateTimeField'):
            time_obj = datetime.datetime.now()
            time_list = [
                ['','------'],
                [time_obj,'Today'],
                [time_obj - datetime.timedelta(7),'七天内'],
                [time_obj.replace(day=1),'本月'],
                [time_obj - datetime.timedelta(90),'三个月内'],
                [time_obj.replace(month=1,day=1),'YearToDay(YTD)'],
                ['','ALL'],
            ]

            for i in time_list:
                selected = ''
                time_to_str = ''if not i[0] else  "%s-%s-%s"%(i[0].year,i[0].month,i[0].day)
                if  "%s__gte"% filter_column in admin_class.filter_condtions:  # 当前字段被过滤了
                    print('-------------gte')
                    if time_to_str == admin_class.filter_condtions.get("%s__gte"% filter_column):  # 当前值被选中了
                        selected = 'selected'
                option = "<option value='%s' %s>%s</option>" % \
                         (time_to_str ,selected,i[1])
                filter_ele += option

    filter_ele += "</select></div>"
    return mark_safe(filter_ele)



@register.simple_tag
def  build_table_row(obj,admin_class):
    """生成一条记录的html element"""

    ele = ""
    if admin_class.list_display:
        for index,column_name in enumerate(admin_class.list_display):

            column_obj = admin_class.model._meta.get_field(column_name)
            if column_obj.choices: #get_xxx_display
                column_data = getattr(obj,'get_%s_display'% column_name)()
            else:
                column_data = getattr(obj,column_name)

            td_ele = "<td>%s</td>" % column_data
            if index == 0:
                td_ele = "<td><a href='%s/change/'>%s</a></td>"% (obj.id,column_data)

            ele += td_ele
    else:
        td_ele = "<td><a href='%s/change/'>%s</a></td>" % (obj.id,obj)

        ele += td_ele
    return mark_safe(ele)



@register.simple_tag
def get_model_name(admin_class):
    return admin_class.model._meta.model_name.upper()



@register.simple_tag
def get_sorted_column(column,sorted_column,forloop):
    #sorted_column = {'name': '-0'}
    if column in sorted_column:#这一列被排序了,
        #你要判断上一次排序是什么顺序,本次取反
        last_sort_index = sorted_column[column]
        if last_sort_index.startswith('-'):
            this_time_sort_index = last_sort_index.strip('-')
        else:
            this_time_sort_index = '-%s' % last_sort_index
        return this_time_sort_index
    else:
        return forloop


@register.simple_tag
def render_filtered_args(admin_class,render_html=True):
    '''拼接筛选的字段'''
    if admin_class.filter_condtions:
        ele = ''
        for k,v in admin_class.filter_condtions.items():
            ele += '&%s=%s' %(k,v)
        if render_html:
            return mark_safe(ele)
        else:
            return ele
    else:
        return ''


@register.simple_tag
def render_sorted_arrow(column,sorted_column):
    if column in sorted_column:  # 这一列被排序了,
        last_sort_index = sorted_column[column]
        if last_sort_index.startswith('-'):
            arrow_direction = 'bottom'
        else:
            arrow_direction = 'top'
        ele = '''<span class="glyphicon glyphicon-triangle-%s" aria-hidden="true"></span>''' % arrow_direction
        return mark_safe(ele)
    return ''


@register.simple_tag
def render_paginator(querysets,admin_class,sorted_column):
    ele = '''
      <ul class="pagination">
    '''
    for i in querysets.paginator.page_range:
        if abs(querysets.number - i) < 2 :#display btn
            active = ''
            if querysets.number == i : #current page
                active = 'active'
            filter_ele = render_filtered_args(admin_class)

            sorted_ele = ''
            if sorted_column:
                sorted_ele = '&_o=%s' % list(sorted_column.values())[0]

            p_ele = '''<li class="%s"><a href="?_page=%s%s%s">%s</a></li>'''  % (active,i,filter_ele,sorted_ele,i)

            ele += p_ele


    ele += "</ul>"

    return mark_safe(ele)


@register.simple_tag
def get_current_sorted_column_index(sorted_column):

    return list(sorted_column.values())[0] if sorted_column else ''



@register.simple_tag
def get_obj_field_val(form_obj,field):
    '''返回model obj具体字段的值'''

    return getattr(form_obj.instance,field)


@register.simple_tag
def get_available_m2m_data(field_name,form_obj,admin_class):
    """返回的是m2m字段关联表的所有数据"""

    field_obj = admin_class.model._meta.get_field(field_name)
    obj_list = set(field_obj.related_model.objects.all())

    selected_data = set(getattr(form_obj.instance ,field_name).all())

    return obj_list - selected_data




    return obj_list

@register.simple_tag
def get_selected_m2m_data(field_name,form_obj,admin_class):
    """返回已选的m2m数据"""

    selected_data = getattr(form_obj.instance ,field_name).all()

    return selected_data
kingadmin_tags.py
from django.shortcuts import render,redirect
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from django import conf
from django.db.models import Q
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage
from kingadmin import app_setup
from kingadmin import form_handle
app_setup.kingadmin_auto_discover()


from kingadmin.sites import  site
print("sites.",site.enabled_admins)

# for k,v in site.enabled_admins.items():
#     for table_name,admin_class in v.items():
#         print(table_name,id(admin_class))
# # Create your views here.


def app_index(request):
    #enabled_admins =

    return render(request,'kingadmin/app_index.html', {'site':site})

def get_filter_result(request,querysets):
    filter_conditions = {}
    for key,val in request.GET.items():
        if key in ('_page','_o','_q'):continue
        if val:
            filter_conditions[key] =  val


    print("filter_conditions",filter_conditions)
    return querysets.filter(**filter_conditions),filter_conditions

def get_orderby_result(request,querysets,admin_class):
    """排序"""

    current_ordered_column = {}
    orderby_index = request.GET.get('_o')
    if orderby_index:
        orderby_key =  admin_class.list_display[ abs(int(orderby_index)) ]
        current_ordered_column[orderby_key] = orderby_index #为了让前端知道当前排序的列

        if orderby_index.startswith('-'):
            orderby_key =  '-'+ orderby_key

        return querysets.order_by(orderby_key),current_ordered_column
    else:
        return querysets,current_ordered_column


def get_serached_result(request,querysets,admin_class):


    search_key = request.GET.get('_q')
    if search_key :
        q = Q()
        q.connector = 'OR'

        for search_field in admin_class.search_fields:
            q.children.append(("%s__contains"% search_field,search_key))


        return  querysets.filter(q)
    return querysets




# @login_required
def table_obj_list(request,app_name,model_name):
    """取出指定model里的数据返回给前端"""
    #print("app_name,model_name:",site.enabled_admins[app_name][model_name])
    admin_class = site.enabled_admins[app_name][model_name]
    querysets = admin_class.model.objects.all().order_by('-id')

    querysets,filter_condtions  = get_filter_result(request,querysets)
    admin_class.filter_condtions = filter_condtions

    #searched queryset result
    querysets = get_serached_result(request,querysets,admin_class)
    admin_class.search_key = request.GET.get('_q','')

    #sorted querysets
    querysets,sorted_column = get_orderby_result(request,querysets,admin_class)


    paginator = Paginator(querysets, 2) # Show 25 contacts per page

    page = request.GET.get('_page')
    try:
        querysets = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        querysets = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        querysets = paginator.page(paginator.num_pages)
    print(request.GET)
    #print("admin class",admin_class.model )

    return render(request,'kingadmin/table_obj_list.html', {'querysets':querysets,
                                                            'admin_class':admin_class,
                                                            'sorted_column':sorted_column})


# @login_required
def table_obj_change(request,app_name,model_name,obj_id):
    """kingadmin 数据修改页"""
    admin_class = site.enabled_admins[app_name][model_name]
    model_form = form_handle.create_dynamic_model_form(admin_class)
    obj = admin_class.model.objects.get(id=obj_id)
    if request.method == "GET":
        form_obj = model_form(instance=obj)
    elif request.method == "POST":
        form_obj = model_form(instance=obj,data=request.POST)
        if form_obj.is_valid():
            form_obj.save()
            return redirect("/kingadmin/%s/%s/" %(app_name,model_name))

    # from crm.forms import CustomerForm
    #
    # form_obj = CustomerForm()
    return render(request,'kingadmin/table_obj_change.html',locals())


def table_obj_add(request,app_name,model_name):
    admin_class = site.enabled_admins[app_name][model_name]
    model_form = form_handle.create_dynamic_model_form(admin_class,form_add=True)
    if request.method == "GET":
        form_obj = model_form()
    elif request.method == "POST":
        form_obj = model_form(data=request.POST)
        if form_obj.is_valid():
            form_obj.save()
            return redirect("/kingadmin/%s/%s/" % (app_name, model_name))

    return render(request,'kingadmin/table_obj_add.html',locals())


def acc_login(request):
    error_msg = ''
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')

        user = authenticate(username=username,password=password)
        if user:
            print("passed authencation",user)
            login(request,user)
            #request.user = user

            return  redirect( request.GET.get('next','/kingadmin/') )
        else:
            error_msg = "Wrong username or password!"
    return render(request, 'kingadmin/login.html', {'error_msg':error_msg})


def acc_logout(request):
    logout(request)
    return redirect("/login/")
views

猜你喜欢

转载自www.cnblogs.com/jintian/p/11324566.html