我设置了一个HyperlinkedModelSerializer,其中使用HyperlinkedRelatedField对其他模型进行了一些引用。这很好用:
var griddle_prep = function($el){
if(!$el.data('init')){
$el.addClass('griddle-initialized');
$el.data('init',$el.html());
}
};
var griddle_update = function($el){
var per_row = 6,
window_width = $(window).width();
// instead of calculating heights we're just going to piggyback breakpoints
// to determine how many items are in each row, see _griddle.scss
if(window_width<960){
per_row = 5;
}
if(window_width<768){
per_row = 4;
}
if(window_width<650){
per_row = 3;
}
if(window_width<530){
per_row = 2;
}
// proceed with updating the markup
if($el.data('init')) {
// wipe out the existing markup and use the stored 'template'
$el.html($el.data('init'));
// wrap each 'row' with a wrapper
var divs = $el.children(),
markup = '<div class="wrapper group griddle-row">',
i = 0;
divs.each(function(){
if(i>=per_row){
markup += '</div>';
markup += '<div class="wrapper group griddle-row">';
i = 0;
}
markup += $(this).wrap('<div>').parent().html();
i++;
});
markup += '</div>';
$el.html(markup);
}
};
var griddle_clean_up = function($el){
var $details = $el.find('.griddle-detail-display');
if($details.length){
$details.remove();
$el.find('.griddle-active').removeClass('griddle-active');
}
};
var griddle_position_indicator = function($el,$details){
var indicator_left = $el.offset().left + parseInt($el.outerWidth()/2,10);
$details.find('.griddle-indicator').css('left',indicator_left+'px');
};
var $griddles = $('.griddle');
if($griddles.length){
$('.griddle-details').hide();
// bind our details
$('body').on('click','.griddle-trigger',function(e){
e.preventDefault();
var $this = $(this),
$row = $this.parents('.griddle-row'),
target_row_index = $row.index(),
$griddle = $row.parents('.griddle'),
toggle = $(this).hasClass('griddle-active'),
$current_row = $griddle.find('.griddle-detail-display'),
$existing_details = $current_row,
current_row_index = $current_row.prev().index(),
$target_details = $this.parents('.griddle-item').find('.griddle-details').clone().show().removeAttr('id').addClass('griddle-detail-display').hide();
$griddle.find('.griddle-active').removeClass('griddle-active');
if(toggle){
$existing_details.slideUp('fast',function(){
$existing_details.remove();
});
}else{
// is a current row already displayed?
if(current_row_index>-1){
// check to see if we're just swapping out
if(target_row_index===current_row_index){
// just swap it out
$current_row.remove();
$row.after($target_details);
$target_details.show();
} else {
// remove the non-applicable row
$existing_details.slideUp('fast',function(){
$existing_details.remove();
});
// show the applicable row
$row.after($target_details);
$griddle.find('.griddle-detail-display').slideDown('fast');
}
} else {
// no current row, just slide it down
$row.after($target_details);
$griddle.find('.griddle-detail-display').slideDown('fast');
}
$this.addClass('griddle-active');
griddle_position_indicator($this,$target_details);
}
});
$griddles.each(function(){
var $griddle = $(this);
// going to grab the griddle HTML because we're going to be swapping it in and out when resizing
griddle_prep($griddle);
// init the rows
griddle_update($griddle);
// update the rows on resize
$(window).smartresize(function(){
griddle_clean_up($griddle);
griddle_update($griddle);
});
});
}
但是我需要对其他一些字段进行一些数据转换,所以我覆盖了class LicenseSerializer(serializers.HyperlinkedModelSerializer):
style = serializers.HyperlinkedRelatedField(
view_name='styles-detail',
queryset=Style.objects.all()
)
order = serializers.HyperlinkedRelatedField(
view_name='orders-detail',
queryset=Order.objects.all()
)
:
to_internal_value
此时HyperlinkedRelatedField不再有效。我收到一个错误说:
def to_internal_value(self, data):
return data
至少在我看来,HyperlinkedRelatedField不再有效吗?
这是Serializer崩溃时的转储:
Cannot assign "'[hyperlinked identity url]'": "[Model.attribute]" must be a "[hyperlinked model]" instance.
我在这里做错了什么?
谢谢你的时间!
答案 0 :(得分:1)
你不能这样做:
def to_internal_value(self, data):
return data
Serializer.to_internal_value
验证收到的数据(data
)并将其转换为在ORM级别有用的类型。
对于HyperLinkedRelatedField
,它会检索(通过HyperLinkedRelatedField.to_internal_value
)要链接的对象。在您的情况下,您直接传递了包含URL而不是对象的未经验证的data
。如果数据只包含原始类型,但仍然不安全,那么这可能有效。
如果您要进行任何转换,请先检索对象:
def to_internal_value(self, data):
validated_data = super().to_internal_value(data)
# Your transformations on validated_data
return validated_data