django条件权限和初始属性

时间:2017-02-01 07:23:32

标签: python django django-admin

我遇到有关条件许可和设置初始值的问题。

我的models.py是:

from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver

from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _

import re
from smart_selects.db_fields import ChainedForeignKey 

# Create your models here.



class Product(models.Model) :
    name = models.CharField(max_length=20, verbose_name='Name', help_text='Product Name')
    u_name = models.CharField(max_length=20,  editable=False)
    description = models.CharField(max_length=40, verbose_name='Description', help_text='Product Description')

    def clean(self) :
        self.u_name = re.sub(r'[^a-zA-Z0-9]','', self.name.lower())
        existing = Product.objects.filter(u_name = self.u_name)
        if len(existing) > 0 :
            if self.pk == None :
                raise ValidationError('Duplicate Name : %s' %(existing[0].name))
            else :
                if existing[0].id != self.id :
                    raise ValidationError('Duplicate Name : %s' %(existing[0].name))

    def __str__(self):              # __unicode__ on Python 2
        return self.name

    class Meta:
        verbose_name = 'Product'



class Warehouse(models.Model):
    name = models.CharField(max_length=20, verbose_name='Name', help_text='Warehouse Name')
    u_name = models.CharField(max_length=20, editable=False)
    description = models.CharField(max_length=40, verbose_name='Description', help_text='Warehouse Description')

    def clean(self) :
        self.u_name = re.sub(r'[^a-zA-Z0-9]','', self.name.lower())
        existing = Warehouse.objects.filter(u_name = self.u_name)
        if len(existing) > 0 :
            if self.pk == None :
                raise ValidationError('Duplicate Name : %s' %(existing[0].name))
            else :
                if existing[0].id != self.id :
                    raise ValidationError('Duplicate Name : %s' %(existing[0].name))

    def __str__(self):              # __unicode__ on Python 2
        return self.name

    class Meta:
        verbose_name = 'Warehouse'


class WarehouseStock(models.Model) :
    warehouse = models.ForeignKey(Warehouse, on_delete=models.PROTECT, verbose_name='Warehouse', help_text='Warehouse', editable=False)
    product = models.ForeignKey(Product, on_delete=models.PROTECT, verbose_name='Product', help_text='Product', editable=False)
    qty = models.IntegerField(verbose_name='Quantity', null=True, editable=False)

    def __str__(self):              # __unicode__ on Python 2
        return self.product.name

    class Meta:
        verbose_name = 'Warehouse Stock'

class UserProfile(models.Model) :
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE, verbose_name='Warehouse', help_text='Warehouse')
    def __str__(self):              # __unicode__ on Python 2
        return self.user

    class Meta:
        verbose_name = 'Ext Profile'


class StockIn(models.Model) :
    code = models.CharField(max_length=20, verbose_name='Code', help_text='Code')
    u_code = models.CharField(max_length=20, editable=False)
    user = models.ForeignKey(User, on_delete=models.PROTECT, editable=False)
    warehouse = models.ForeignKey(Warehouse,
        on_delete=models.PROTECT,
        verbose_name='Warehouse',
        help_text='Warehouse',
        editable=False,
    )

    def clean(self) :
        self.u_code = re.sub(r'[^a-zA-Z0-9]','', self.code.lower())
        existing = StockMove.objects.filter(u_code = self.u_code)
        if len(existing) > 0 :
            if self.pk == None :
                raise ValidationError('Duplicate Code : %s' %(existing[0].code))
            else :
                if existing[0].id != self.id :
                    raise ValidationError('Duplicate Code : %s' %(existing[0].code))

    def __str__(self):              # __unicode__ on Python 2
        return self.code

    class Meta:
        verbose_name = 'Stock In'

我想要的StockIn admin是(伪代码):

if action == add :
    if request.user has UserProfile.warehouse :
        set stockin.warehouse initial value to UserProfile.warehouse
        set stockin.user initial value to request.user
    else :
        deny
else :
    if request.user != stockin.user :
        deny

我在admin.py中的尝试是

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User

# Register your models here.
from .models import Product, Warehouse, WarehouseStock, UserProfile
from .models import StockIn

admin.site.register(Product,)
admin.site.register(Warehouse,)
admin.site.register(WarehouseStock,)


class UserProfileInline(admin.StackedInline):
    model = UserProfile
    #can_delete = False
    #verbose_name_plural = 'employee'

# Define a new User admin
class UserAdmin(BaseUserAdmin):
    inlines = (UserProfileInline, )


admin.site.unregister(User)
admin.site.register(User, UserAdmin)


class StockInAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super(StockInAdmin, self).get_form(request, obj, **kwargs)
        if form.user == None :
            try :
                form.base_fields['user'].initial = request.user
                form.base_fields['warehouse'].initial = UserProfile.objects.fiter(user = request.user)[0].warehouse
                return form
            except :
                raise ValidationError('You havde no warehouse')
        if form.base_fields['user'] != request.user :
            raise ValidationError('You are not the owner')
        return form

admin.site.register(StockIn, StockInAdmin)

但它报告:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/admin/inax/stockin/add/

Django Version: 1.10.4
Python Version: 2.7.12
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'smart_selects',
 'inax.apps.InaxConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/exception.py" in inner
  39.             response = get_response(request)

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in wrapper
  544.                 return self.admin_site.admin_view(view)(*args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
  149.                     response = view_func(request, *args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
  57.         response = view_func(request, *args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in inner
  211.             return view(request, *args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in add_view
  1509.         return self.changeform_view(request, None, form_url, extra_context)

File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper
  67.             return bound_func(*args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
  149.                     response = view_func(request, *args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func
  63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in inner
  185.                     return func(*args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in changeform_view
  1438.         ModelForm = self.get_form(request, obj)

File "/home/bino/Documents/inax/apps/mysite/inax/admin.py" in get_form
  32.         form = super(StockInAdmin, self).get_form(request, obj, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in get_form
  608.             fields = flatten_fieldsets(self.get_fieldsets(request, obj))

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in get_fieldsets
  298.         return [(None, {'fields': self.get_fields(request, obj)})]

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in get_fields
  597.         form = self.get_form(request, obj, fields=None)

File "/home/bino/Documents/inax/apps/mysite/inax/admin.py" in get_form
  33.         if form.user == None :

Exception Type: AttributeError at /admin/inax/stockin/add/
Exception Value: type object 'StockInForm' has no attribute 'user'
请告诉我如何正确地做到这一点。

此致 -bino -

1 个答案:

答案 0 :(得分:1)

您正在检查if form.user == None而不是if not form.base_fields['user']

它正在检查表单上的用户属性,但就表单而言,用户只是一个字段。

你必须首先了解超级方法。 super将只调用继承的类get_form方法。如果您遵循代码,您将理解get_form(超级类)的ModelAdmin方法不会返回任何内容。

因此您必须从self访问所有表单实例。

所以你必须把它改成:

def get_form(self, request, obj=None, **kwargs):
        super(StockInAdmin, self).get_form(request, obj, **kwargs)
        if self.form.fields['user'] is None: